🎉为备战蓝桥杯,从今天开始更几期蓝桥杯的内容,总结相关试题,分析解题思路,铺好康庄大道,直到巅峰🎉

🎉🎉目前持续总结更新🎉🎉

💗 大家好🤗🤗🤗,我是左手の明天!💗

📆  最近更新:2022 年 4 月 6 日,左手の明天的第 218 篇原创博客

目录

🚩换零钞

🚩激光样式

🚩格雷码

🚩分数

🚩调手表

🚩付账问题

🚩搭积木

🚩矩阵求和

🚩星期一

🚩乘积尾零

🚩第几个幸运数

🚩打印图形


👍👍👍👍👍👍

🌟🌟 预祝各位能够得到好的名次 🌟🌟


🚩换零钞

⭐️题目

x星球的钞票的面额只有:100元,5元,2元,1元,共4种。小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。小明有点强迫症,他坚持要求200元换出的零钞中2元的张数刚好是1元的张数的10倍,剩下的当然都是5元面额的。银行的工作人员有点为难,你能帮助算出:在满足小明要求的前提下,最少要换给他多少张钞票吗?(5元,2元,1元面额的必须都有,不能是0)

⭐️代码

1.	#include<iostream> 
2.	using namespace std;
3.	int main(){
4.	    for(int i=1;i<40;i++){
5.	        for(int j=1;j<200;j++){
6.	            if(5*i+2*10*j+1*j==200)
7.	                cout<<"5*"<<i<<"+2*"<<10*j<<"+1*"<<j<<"="<<5*i+2*10*j+1*j<<"(一共"<<i+10*j+j<<"张)"<<endl;
8.	        }
9.	    }
10.	    return 0;
11.	}

🎉答案:74


🚩激光样式

⭐️题目

x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?

⭐️分析

显然,如果只有3台机器,一共可以成5种样式,即:

  • 全都关上
  • 开一台,共3种
  • 开两台,只1种

30台思路很简单,暴力搜索,30个灯光从左到右,从左边第一个开始,第一个可以开关,第二个要根据左边的灯光是否开启来取值,以此类推。。。

⭐️代码

1.	#include<iostream> 
2.	#include<string.h> 
3.	using namespace std;
4.	int ans = 0;
5.	int x[31];//0代表关,1代表开 
6.	 
7.	void dfs(int index){
8.	    if(index == 30){
9.	        ans++;
10.	        return;
11.	    }
12.	    if(index == 0 || x[index-1] == 0){  //第一个灯光可以取0或1,当前灯光左边要是没开,那当前灯光可以取0和1 
13.	        for(int i=0;i<=1;i++){
14.	            x[index] = i;
15.	            dfs(index+1);
16.	            x[index] = 0;
17.	        }
18.	    }
19.	    else{ //左边的灯光开了,那当前灯光只能关闭(取0) 
20.	        dfs(index+1);
21.	    }
22.	}
23.	 
24.	int main(){
25.	    memset(x,0,31*sizeof(int));
26.	    dfs(0);
27.	    cout<<ans<<endl;
28.	    return 0;
29.	}

🎉答案:2178309


🚩格雷码

⭐️题目

格雷码是以n位的二进制来表示数。

与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同。

首尾两个数字也要求只有1位之差。

有很多算法来生成格雷码。以下是较常见的一种:

从编码全0开始生成。

当产生第奇数个数时,只把当前数字最末位改变(0变1,1变0)

当产生第偶数个数时,先找到最右边的一个1,把它左边的数字改变。

用这个规则产生的4位格雷码序列如下:

0000

0001

0011

0010

0110

0111

0101

0100

1100

1101

1111

1110

1010

1011

1001

1000

⭐️代码

1.	#include <stdio.h>
2.	void show(int a,int n){
3.	    int i;
4.	    int msk = 1;
5.	    for(i=0; i<n-1; i++) msk = msk << 1;
6.	    for(i=0; i<n; i++){
7.	        printf((a & msk)? "1" : "0");
8.	        msk = msk >> 1;
9.	    }
10.	    printf("\n");
11.	} 
12.	void f(int n){
13.	    int i;
14.	    int num = 1;
15.	    for(i=0; i<n; i++) num = num<<1;
16.	    int a = 0;
17.	    for(i=0; i<num; i++){
18.	        show(a,n);
19.	        if(i%2==0){
20.	            a = a ^ 1;
21.	        }
22.	        else{
23.	            a = a^((a&(-a))<<1); 
24.	        }
25.	    }
26.	}
27.	int main(){
28.	    f(4);
29.	    return 0;
30.	}

🚩分数

⭐️题目

1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ....

每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来。 类似: 3/2

当然,这只是加了前2项而已。分子分母要求互质。

注意: 需要提交的是已经约分过的分数,中间任何位置不能含有空格。 请不要填写任何多余的文字或符号。

⭐️思路

  • 此题规模较小,直接用等比公式求和就行,得出结果后看看能不能约分。
  • 展开式子:[(1/2)^0 + (1/2) ^1 + (1/2) ^2+ ……+(1/2) ^19 ] == [2 ^19+2 ^18+ ……+2 ^0] / (2 ^19) == (2 ^20 -1)/(2 ^19)之后再约分

⭐️代码

#include <iostream>

using namespace std;

int pow_2(int n){
	int x = 2;			//基数
	int res = 1;		//答案
	while(n > 0){		//指数大于0 
		if(n & 1){		//奇次幂 
			res *= x;	//乘以基数 
		}
		n >>= 1;		//指数减半 
		x *= x;			//基数相乘 
	} 
	return res;			//返回结果 
}

int gcd(int a,int b){
	if(b == 0)	return a;
	return gcd(b,a%b);
}


int main(){
	int x = gcd(pow_2(20)-1,pow_2(19));//最大公约数
	cout << (pow_2(20)-1)/x << "/" << (pow_2(19)/x) << endl;	//最终结果
	return 0;
}

🚩调手表

⭐️题目

小明买了块高端大气上档次的电子手表,他正准备调时间呢。

在 M78 星云,时间的计量单位和地球上不同,M78 星云的一个小时有 n 分钟。

大家都知道,手表只有一个按钮可以把当前的数加一。在调分钟的时候,如果当前显示的数是 0 ,那么按一下按钮就会变成 1,再按一次变成 2 。如果当前的数是 n - 1,按一次后会变成 0 。

作为强迫症患者,小明一定要把手表的时间调对。如果手表上的时间比当前时间多1,则要按 n - 1 次加一按钮才能调回正确时间。

小明想,如果手表可以再添加一个按钮,表示把当前的数加 k 该多好啊……

他想知道,如果有了这个 +k 按钮,按照最优策略按键,从任意一个分钟数调到另外任意一个分钟数最多要按多少次。

注意,按 +k 按钮时,如果加k后数字超过n-1,则会对n取模。

比如,n=10, k=6 的时候,假设当前时间是0,连按2次 +k 按钮,则调为2。

「输入格式」

一行两个整数 n, k

「输出格式」

一行一个整数

表示:按照最优策略按键,从一个时间调到另一个时间最多要按多少次。

「样例输入」

5 3

「样例输出」

2

「样例解释」

如果时间正确则按0次。否则要按的次数和操作系列之间的关系如下:

1:+1

2:+1, +1

3:+3

4:+3, +1

「数据范围」

对于 30% 的数据 0 < k < n <= 5

对于 60% 的数据 0 < k < n <= 100

对于 100% 的数据 0 < k < n <= 100000

⭐️分析

要求从一个时间到另一个时间按的最多的次数。

按照最优策略,最优,就是按的次数最少,应该可以想到BFS最短路径

对整个0 - n-1 进行BFS,从0开始广搜,两种情况:+1取模 or +k取模 ,接着判断取模后的数字是否入过队,如果入过,则跳过,否则,标记并入队。因为是对整个0 - n-1 进行搜索,没有break条件,只能运行至队列为空;因为有取模和标记的限制,所以只会限制在0 - n-1 ;

⭐️BFS思路

BFS的思想,用一个队列先存储第一个走到的时间状态,即时间0,步数为0,然后根据队首元素往后搜可能到达的两个时间点(即+1之后的时间和+k之后的时间),如果这两个时间没有走过那就存进队列,对应时间状态的步数+1,最后找到这些步数里的最大值就行

⭐️代码

#include <bits/stdc++.h>
using namespace std;
int ans=0,n,k,t,book[100001];
typedef struct
{ int num;//当前状态里的时间 
  int step; //走到这个状态所需要的步数 
}Status;//定义状态结构体 
queue<Status> q;
int main() 
{ 
  	cin>>n>>k;
  	Status start,f,now1;//起始    头    现在 
  	start.step=0;
  	start.num=0;
  	book[0]=1;
  	q.push(start);//先插入当前状态 
  	while(!q.empty())
  	{
  		f=q.front();
  		q.pop();
  		t=(f.num+1)%n;//按+1键后的时间 
  		if(!book[t])//如果这个时间没有走过 
  		{ book[t]=1;//标记走过 
		  now1.num=t;
  		  now1.step=f.step+1;
  		  ans=max(ans,now1.step); //更新答案 
  		  q.push(now1);//把当前状态插入 
  		}
  		t=(f.num+k)%n;//按+k键后的时间 
  		if(!book[t])//如果这个时间没有走过
  		{ book[t]=1;//标记走过 
		  now1.num=t;
  		  now1.step=f.step+1;
  		  ans=max(ans,now1.step);
  		  q.push(now1);//把当前状态插入
  		}
  	}
  	cout<<ans;
	return 0;
	
}

🚩付账问题

⭐️题目

几个人⼀起出去吃饭是常有的事。但在结帐的时候,常常会出现⼀些争执。

现在有 n 个人出去吃饭,他们总共消费了 S 元。其中第 i 个人带了 ai 元。幸运的是,所有⼈带的钱的总数是足够付账的,但现在问题来了:每个⼈分别要出多少钱呢?

为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个⼈付的钱的标准差最小。这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是 1 分钱的整数倍。你需要输出最小的标准差是多少。

标准差的介绍:标准差是多个数与它们平均数差值的平⽅平均数,⼀般⽤于刻画这些数之间的“偏差有多大”。形式化地说,设第 i 个⼈付的钱为 bi 元,那么标准差为 

「输入格式」

第⼀⾏包含两个整数 n、S;
第⼆⾏包含 n 个⾮负整数 a1, …, an。

「输出格式」

输出最⼩的标准差,四舍五⼊保留 4 位⼩数。

「数据范围」

1≤n≤5×10 ,
0≤ai,S≤10

「输入样例1」

5 2333
666 666 666 666 666

「输出样例1」

0.0000

「输入样例2」

10 30
2 1 4 7 4 8 3 6 4 7

「输出样例2」

0.7928

⭐️分析

首先这是一个“贪心问题”,为了使标准差最小,每一个人出的钱==bi==必须接近平均值。 

  • (1)ai<=bi时:必须交上所有的钱,这样才能保证标准差尽可能的小
  • (2)ai>bi时:这类人不仅要交平均值S/n,还要平摊没带够钱的人的费用
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
LL S;
double ans,avg;

void work()
{
    scanf("%d %lld",&n,&S);
    ans = 0.0;
    avg = 1.0*S/n; //总平均值
    LL *a = new LL[n]; //存储数据
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]);
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        if(a[i]*(n-i)<S) //比平均数小的话全额上缴
        {
            ans+=(a[i]-avg)*(a[i]-avg); //累加到方差上
            S-=a[i]; //已支付a[i],应支付额变小
        }
        else //当前及后续每个人的数额都超出当前值
        {
            double cur_avg = 1.0*S/(n-i); //算当前均值
            ans+=(avg-cur_avg)*(avg-cur_avg)*(n-i);
            break;
        }
    }
    printf("%.4lf\n",sqrt(ans/n));
}
int main()
{
    work();
    return 0;
}

在这里插入图片描述


 🚩搭积木

⭐️题目

小明对搭积木非常感兴趣。他的积木都是同样大小的正立方体。

在搭积木时,小明选取 m 块积木作为地基,将他们在桌子上一字排开,中间不留空隙,并称其为第0层。随后,小明可以在上面摆放第1层,第2层,……,最多摆放至第n层。摆放积木必须遵循三条规则:

规则1:每块积木必须紧挨着放置在某一块积木的正上方,与其下一层的积木对齐;

规则2:同一层中的积木必须连续摆放,中间不能留有空隙;

规则3:小明不喜欢的位置不能放置积木。

其中,小明不喜欢的位置都被标在了图纸上。图纸共有n行,从下至上的每一行分别对应积木的第1层至第n层。每一行都有m个字符,字符可能是‘.’或‘X’,其中‘X’表示这个位置是小明不喜欢的。

现在,小明想要知道,共有多少种放置积木的方案。他找到了参加蓝桥杯的你来帮他计算这个答案。

由于这个答案可能很大,你只需要回答这个答案对1000000007(十亿零七)取模后的结果。

注意:地基上什么都不放,也算作是方案之一种。

【输出格式】

输出一个整数,表示答案对1000000007取模后的结果。

【样例输入1】

2 3

..X

.X.

【样例输出1】

4

【样例说明1】

成功的摆放有(其中O表示放置积木):

(1)

..X

.X.

(2)

..X

OX.

(3)

O.X

OX.

(4)

..X

.XO

【样例输入2】

3 3

..X

.X.

...

【样例输出2】

16

【数据规模约定】

对于10%的数据,n=1,m<=30;

对于40%的数据,n<=10,m<=30;

对于100%的数据,n<=100,m<=100。

⭐️思路

首先此题解决方案用到状态转移,且子问题独立,很显然是dp,但如果只是单纯的暴力dp的话会超时,那么就用到了二维前缀和优化

两个函数:

  • check[i][j]:表示第i层前j个中有多少个‘X’
  • dp[l][r] = v:表示当前层中的[l,r]的方法数是v

check其实就是前缀和操作,对每一层进行前缀和运算,规定积木从下到上分别是第n层,第n-1层,最上面是第一层,首先用check来更新最低层dp的值,然后从最低层开始向上传递,即从大区间枚举到小区间后得出的方法数。

🍊转移方程:

dp[l][r]+=dp[l-1][r]+dp[l][r+1]-dp[l-1][r+1]

因为l和r分别是从两端开始向内走,所以更新区间时也是由外向内更新,当更新区间[l,r]时,值区间[l-1][r]+区间[l][r+1]-区间[l-1][r+1],因为dp[l-1][r]和dp[l][r+1]中包括的是[l-1,r+1]+[l,r],所以要减去。

⭐️代码

#include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
typedef long long LL;
const int maxn = 110;
LL dp[maxn][maxn]; //dp[l][r]=v记录的是当前层中的[l,r]的方法数为v(初始dp是dp[n][l][r])

//转移为dp[l][r]+=dp[l-1][r]+dp[l][r+1]-dp[l-1][r+1](因为dp[l-1][r]和dp[l][r+1]中包括的是[l-1,r+1]+[l,r]所以要减去)
//由题意可知初始化为第n层的方法数,即从大区间枚举到小区间后得出的方法数
//转移时若[l,r]中没有X,则方法数为dp[l][r]+=dp[l-1][r]+dp[l][r+1]-dp[l-1][r+1],相当于向上传递,反之从这一层开始[l,r]区间的方法数就为0
int check[maxn][maxn];
int main(){
    int n,m;
    char str[maxn];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",str+1);
        for(int j=1;j<=m;j++){
            check[i][j]=check[i][j-1];    //一个比较巧妙的方法
            if(str[j]=='X'){
                check[i][j]++;
            }
        }
    }
    LL ans=1;    //没有放也是一种
    for(int i=1;i<=m;i++){    //初始化
        for(int j=m;j>=i;j--){
            if(check[n][j]-check[n][i-1]==0){
                ans++;
                dp[i][j]=dp[i][j+1]+dp[i-1][j]-dp[i-1][j+1]+1;
            }
        }
    }
    for(int t=n-1;t>0;t--){    //状态
        for(int i=1;i<=m;i++){
            for(int j=m;j>=i;j--){
                if(check[t][j]-check[t][i-1]==0){
                    ans=(ans+dp[i][j])%MOD;
                    dp[i][j]=(dp[i][j]+dp[i-1][j]+dp[i][j+1]-dp[i-1][j+1])%MOD;
                }else{
                    dp[i][j]=0;
                }
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}

🚩矩阵求和

⭐️题目

经过重重笔试面试的考验,小明成功进入 Macrohard 公司工作。今天小明的任务是填满这么一张表:表有 n 行 n 列,行和列的编号都从1算起。其中第 i 行第 j 个元素的值是 gcd(i, j)的平方,gcd 表示最大公约数,以下是这个表的前四行的前四列:

1  1  1  1

1  4  1  4

1  1  9  1

1  4  1 16

小明突然冒出一个奇怪的想法,他想知道这张表中所有元素的和。由于表过于庞大,他希望借助计算机的力量。

「输入格式」

一行一个正整数 n 意义见题。

「输出格式」

一行一个数,表示所有元素的和。由于答案比较大,请输出模 (10^9 + 7)(即:十亿零七) 后的结果。

「样例输入」

4

「样例输出」

48

「数据范围」

对于 30% 的数据,n <= 1000

存在 10% 的数据,n = 10^5

对于 60% 的数据,n <= 10^6

对于 100% 的数据,n <= 10^7

⭐️思路

因为n的范围到了1e7,所以暴力算出此表所有值然后累加必然会超时,所以需要把题目转换一下,即求(1 * k,2 * k,3 * k……,(n-1) * k,n * k)然后累加,k的含义是此数在表里出现的次数

题目其实就是问:

 ⭐️代码

#pragma GCC optimiza(2) 
#include <iostream>
#include <cstdio>
#include<cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long int ll;
const int N = 1e7+7;
const int mod=1e9+7;

int primes[N], euler[N], cnt ;
bool st[N];

ll s[N];
// 质数存在primes[]中,euler[i] 表示
// i的欧拉函数
// O(n)
void get_eulers(int n)
{
    euler[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            primes[cnt ++ ] = i;
            euler[i] = i - 1;
        }
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0)
            {
                euler[i * primes[j]] = euler[i] * primes[j];
                break;
            }
            euler[i * primes[j]] = euler[i] * (primes[j] - 1);
        }
    }
    s[1]=euler[1];
    for(int i=2;i<=n;i++) s[i]=(s[i-1]+2*euler[i])%mod;
}

int main(){
    int t,n;
    cin>>n;
    
    get_eulers(n);
    
    ll ans=0;
    for(int d=1;d<=n;d++){
    	ans=(ans+s[n/d]*d%mod*d%mod)%mod;
	}
	
	cout<<ans<<endl;
    
}



🚩星期一

 ⭐️题目

整个20世纪(1901年1月1日至2000年12月31日之间),一共有多少个星期一?

(不要告诉我你不知道今天是星期几)

 ⭐️分析

判断1901年1月1日到2000年12月31的每一天是星期几,如果是星期一则统计的个数+1。

1900年之后的日期直接用Excel求解即可。将B2和B3单元格格式改成日期,然后两个日期相减得出天数(需要注意的是1900/1/1减1900/1/2的结果为1,也就是说后一个日期的那一天不算在内,结果会少一天),在C2和C3用WEEKDAY函数求出星期几(WEEKDAY(日期,类型),这里类型用2,结果返回1-7表示星期一到星期日),最后在C4单元格中将B4的天数加上少算的一天,再减掉一开始不完整的那周的6天,然后除7(即c4=(B4+1-6)/7),就得出了有多少个星期一。

 ⭐️代码

#include<bits/stdc++.h>
using namespace std;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int b[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int days(int year,int month)
{
	if(year%400==0||year%4==0&&year%100!=0)
	return b[month];
	else
	return a[month];
}
 
int main()
{
	int year=2000,month=12,day = 31;
	int i=1,ans=0;
	while(!(year==1901&&month==1&&day==1))
	{
		day--;
		i++;
		if(i==8)
		{
			i=1;
			ans++;
		}
		if(day==0)
		{
			day=days(year,month);
			month--;
			if(month==0)
			{
				month=12;
				year--;
			}
		}
		
	}
	cout<<ans<<endl;
	return 0;
}

🚩乘积尾零

 ⭐️题目

如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?

5650 4542 3554 473 946 4114 3871 9073 90 4329
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899
1486 5722 3135 1170 4014 5510 5120 729 2880 9019
2049 698 4582 4346 4427 646 9742 7340 1230 7683
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649
6701 6645 1671 5978 2704 9926 295 3125 3878 6785
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074
689 5510 8243 6114 337 4096 8199 7313 3685 211

注意:需要提交的是一个整数,表示末尾零的个数。不要填写任何多余内容。

⭐️思路

  1. 本题要求的结果是数据相乘的积数和中末尾有几个零。
  2. 题中数据可以拆分成多个质因数的乘积,比如180 = 2乘2乘3乘5乘3,而3的n次方不会在末尾产生0,一个2和5的乘积会在末尾产生一个0,n个2乘5的积可以产生n个0,再看其他的质因数7、11....仅有2和5的组合会产生0且0的个数是2和5中个数较小值。
  3. 假设有n个180,即180n = (2乘2乘3乘5乘3)n,2 出现了 2n 次,3 出现了 2n 次,5 出现了 n 次,那么积数和末尾零的个数等于2、5个数中较小值 n 。

⭐️代码

#include <iostream>
using namespace std;
#include <cmath>    
int main()
{
    int t_cnt,f_cnt,data=0;//二和五的个数统计
    t_cnt=f_cnt=0;
    
    for(int i = 0;i<100;i++)
    {
        cin>>data;
        while(data%5==0)
        {
            f_cnt++;
            data/=5;
        } 
        while(data%2==0)
        {
            t_cnt++;
            data/=2;
        } 
    } 
    cout<<min(t_cnt,f_cnt)<<endl;//使用cmath库函数,也可以如此求解int count = t_cnt>f_cnt?f_cnt:t_cnt;
     
    return 0;
}

🍊答案:31


🚩第几个幸运数

⭐️题目

到x星球旅行的游客都被发给一个整数,作为游客编号。x星的国王有个怪癖,他只喜欢数字3,5和7。国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。前10个幸运数字是:3 5 7 9 15 21 25 27 35 45,因而第11个幸运数字是:49

小明领到了一个幸运数字 59084709587505。去领奖的时候,人家要求他准确说出这是第几个幸运数字,否则领不到奖品。请你帮小明计算一下,59084709587505是第几个幸运数字。

⭐️思路

幸运数字=3x * 5y * 7z ,取一个优先队列,每次把符合条件的数加进去,从小到大依次把队列的每一个数去和3,5,7相乘,得到符合条件得数在加进队列,直到找到幸运数字结束

⭐️代码

#include<iostream>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
int main(){
	set<long long>st;
	priority_queue<long long, vector<long long>, greater<long long> >pq;
	const int ok[3]={3,5,7};
	st.insert(1);
	pq.push(1);
	int times=0;
	while(true){
		long long lucky=pq.top();
		pq.pop();
		if(lucky==59084709587505){//49
			cout<<times<<endl;
			return 0;
		}
		times++;
		for(int i=0;i<3;i++){
			long long b=lucky*ok[i];
			if(!st.count(b)){
				st.insert(b);
				pq.push(b);
			}
		}
	}
	return 0;
} 

🍊答案:1905


🚩打印图形

⭐️题目1

小明在X星球的城堡中发现了如下图形和文字:

rank=3
   * 
  * * 
 *   *  
* * * *
 
rank=5
               *                                                      
              * *                                                     
             *   *                                                    
            * * * *                                                   
           *       *                                                  
          * *     * *                                                 
         *   *   *   *                                                
        * * * * * * * *                                               
       *               *                                              
      * *             * *                                             
     *   *           *   *                                            
    * * * *         * * * *                                           
   *       *       *       *  
  * *     * *     * *     * *  
 *   *   *   *   *   *   *   * 
* * * * * * * * * * * * * * * *  
 
ran=6
                               *                                      
                              * *                                     
                             *   *                                    
                            * * * *                                   
                           *       *                                  
                          * *     * *                                 
                         *   *   *   *                                
                        * * * * * * * *                               
                       *               *                              
                      * *             * *                             
                     *   *           *   *                            
                    * * * *         * * * *                           
                   *       *       *       *                          
                  * *     * *     * *     * *                         
                 *   *   *   *   *   *   *   *                        
                * * * * * * * * * * * * * * * *                       
               *                               *                      
              * *                             * *                     
             *   *                           *   *                    
            * * * *                         * * * *                   
           *       *                       *       *                  
          * *     * *                     * *     * *                 
         *   *   *   *                   *   *   *   *                
        * * * * * * * *                 * * * * * * * *               
       *               *               *               *              
      * *             * *             * *             * *             
     *   *           *   *           *   *           *   *            
    * * * *         * * * *         * * * *         * * * *           
   *       *       *       *       *       *       *       *          
  * *     * *     * *     * *     * *     * *     * *     * *         
 *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *        
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

编写程序实现该图形的打印。

⭐️代码

#include <stdio.h>  
#define N 70
 
void f(char a[][N], int rank, int row, int col)
{
	if(rank==1){
		a[row][col] = '*';
		return;
	}
	
	int w = 1;
	int i;
	for(i=0; i<rank-1; i++) w *= 2;
	
	f(a, rank-1, row, col+w/2);  
	f(a, rank-1, row+w/2, col);
	f(a, rank-1, row+w/2, col+w);
}
 
int main()
{
	char a[N][N];
	int i,j;
	for(i=0;i<N;i++)
	for(j=0;j<N;j++) a[i][j] = ' ';
	
	f(a,6,0,0);
	
	for(i=0; i<N; i++){
		for(j=0; j<N; j++) printf("%c",a[i][j]);
		printf("\n");
	}
	
	return 0;
}

⭐️题目2

 ⭐️代码

#include <stdio.h>
#include <stdlib.h>
void show(char* buf, int w){
    int i,j;
    for(i=0; i<w; i++){
        for(j=0; j<w; j++){
            printf("%c", buf[i*w+j]==0? ' ' : 'o');
        }
        printf("\n");
    }
}

void draw(char* buf, int w, int x, int y, int size){
    if(size==1){
        buf[y*w+x] = 1;
        return;
    }

    int n = size / 3;
    draw(buf, w, x, y, n);
    draw(buf, w, x-n, y ,n);
    draw(buf, w, x+n, y ,n);
    draw(buf, w, x, y-n ,n);
    draw(buf, w, x, y+n ,n);
}

int main()
{
    int N = 3;
    int t = 1;
    int i;
    for(i=0; i<N; i++) t *= 3;
    char* buf = (char*)malloc(t*t);
    for(i=0; i<t*t; i++) buf[i] = 0;
    draw(buf, t, t/2, t/2, t);
    show(buf, t);
    free(buf);
    return 0;
}

未完待续。。。

🍊🍊🍊

总结不易,看到这那就来个三连吧,肝。。。🍺🍺🍺

🍊🍊🍊

署名:左手の明天

更多推荐