前言
- 大家好啊,我是只会C也要参加蓝桥杯的FyHAng。蓝桥杯省赛只剩一个月的冲刺时间,如果大家觉得之前可能复习的不充分不到位,都没有关系,只要跟着我的节奏来,一个月的时间大家都来得及。接下来的一个月,我会每天持续更新三四道题目,并且提供满分题解,帮助大家-----拿省一进国赛!
今天是第一天!
一、纯质数
如果一个正整数只有 1 和它本身两个约数,则称为一个质数(又称素数)。
前几个质数是:2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, ⋅⋅⋅ 。
如果一个质数的所有十进制数位都是质数,我们称它为纯质数。例如:2,3, 5, 7, 23, 37都是纯质数,而 11,13,17,19,29,31 不是纯质数。 当然 1, 4, 3, 5 也不是纯质数。
请问,在 1 到 20210605 中,有多少个纯质数?
题目链接:纯质数
这是第十二届蓝桥杯(2021)国赛的题目,希望大家一定要掌握此题,因为质数的题目在蓝桥杯的比赛中很常见,此题就是一个很好的例题。
我们来分析一下这道题目,需要满足两个条件:
- 这个数本身就是质数
- 这个数每一个数位上的数都是质数
关于质数的题解,无非就是三种方法:
- 暴力法
- 埃氏筛法
- 欧拉筛
今天我用第一种和第二种的方法对该题进行分析。
1、暴力法
大致思路如下:
- 先判断该数是否为纯质数,依次判断该数各数位上的数是否为质数,如果每一位都是质数,则进入下一步,否则pass;
- 再判断是否为质数。
(注:先判断是否为纯质数,再判断是否为质数,可以大大优化时间,如果反过来运行,很可能会超时哦!)
代码如下:
#include <stdio.h>
#include <stdlib.h>
int czs(int n);
int zs(int x);
int main(int argc, char *argv[])
{
int i;
int cnt = 0;
for(i = 2; i <= 20210605; i++)
{
if(czs(i) && zs(i))
cnt++;
}
printf("%d", cnt);
return 0;
}
int zs(int x)
{
if(x < 2)
return 0;
if(x != 2 && x % 2 == 0)
return 0;
int i;
for(i = 2; i * i <= x; i++)
{
if(x % i == 0)
return 0;
}
return 1;
}
int czs(int n)
{
while(n)
{
int t = n % 10;
if(t == 1 || t == 4 || t == 6 || t == 8 || t == 9 || t == 0)
return 0;
n = n / 10;
}
return 1;
}
2、埃氏筛法
算法核心:
- 从2开始到20210605一路往后筛,用一个p[N]数组记录是否为质数,初始化全为0。
- 如果当前遍历的数对应为0,则把后面所有这个数的倍数都标记为1。(例如:2可以筛掉4、6、8、10…)。
- 如果是1,则表示标记过,不再进行操作。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define N 20210605
int czs(int n)
{
while(n)
{
int t = n % 10;
if(t == 1 || t == 4 || t == 6 || t == 8 || t == 9 || t == 0)
return 0;
n = n / 10;
}
return 1;
}
int p[N] = {0};
int main()
{
int i, j;
for(i = 2; i <= N; i++)
{
if(!p[i])
{
for(j = 2 * i; j < N; j+=i)
{
p[j] = 1;
}
}
}
int cnt = 0;
for(i = 2; i <= N; i++)
{
if(!p[i] && czs(i))
cnt++;
}
printf("%d", cnt);
return 0;
}
二、最少砝码
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 N 的正整数重量。
那么这套砝码最少需要包含多少个砝码?
注意砝码可以放在天平两边。
题目链接:最少砝码
输入格式
输入包含一个正整数 N。输出格式
输出一个整数代表答案。样例输入
7
样例输出
3
样例说明
3 个砝码重量是 1、4、6,可以称出 1 至 7的所有重量。1 = 1;
2 = 6 − 4(天平一边放 6,另一边放 4);3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7=1+6;
少于 3 个砝码不可能称出 1 至 7 的所有重量。*评测用例规模与约定
对于所有评测用例
1 ≤ N ≤ 1000000000
这是第十二届蓝桥杯(2021)省赛的题目,也是很经典的贪心算法的题型。
话不多说,让我们直接来分析题目。
贪心算法
算法核心:
- 尽可能在增加砝码时,使得砝码可称出的重量最大。
代码如下:
#include <stdio.h>
int main()
{
long long N;
int weight = 1;
int count = 1;
int total = 1;
scanf ("%lld", &N);
while (total < N)
{
count++;
weight *= 3;
total += weight;
}
printf ("%lld", count);
return 0;
}
三、灌溉
小蓝负责花园的灌溉工作。
花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。
小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好。
每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。
给定花园水管的位置,请问 k 分钟后,有多少个方格被灌溉好?
题目链接:灌溉
输入描述
输入的第一行包含两个整数 n, m。
第二行包含一个整数 t,表示出水管的数量。
接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r, c 表示第 r 行第 c 列有一个排水管。
接下来一行包含一个整数 kk。
其中,1 ≤ n , m ≤ 100,1 ≤ t ≤ 10,1 ≤ k ≤ 100。
输出描述
输出一个整数,表示答案。
输入输出样例
输入
3 6
2
2 2
3 4
1
输出
9
这是第十二届蓝桥杯(2021)模拟赛的题目,是一道很经典的模拟枚举类型的题目。
模拟
算法核心:
- 暴力枚举啦!
代码如下:
#include<stdio.h>
#include <stdlib.h>
void jg(int x,int y);
int a[101][101];
int n, m, t, i, j, r, c, k, ans = 0;
int main(int argc, char *argv[])
{
scanf("%d%d\n%d", &n, &m, &t);
for(i = 1;i <= t; i++)
{
scanf("%d%d", &r, &c);
jg(r, c);
}
scanf("%d", &k);
if(k > 1)
{
int num = k - 1;
while(num--)
{
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
if(a[i][j])
{
jg(i,j);
}
}
}
}
}
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
if(a[i][j])
{
ans++;
}
}
}
printf("%d", ans);
return 0;
}
void jg(int x,int y)
{
a[x][y] = 1;
if(!a[x-1][y])
{
a[x-1][y] = 1;
}
if(!a[x+1][y])
{
a[x+1][y] = 1;
}
if(!a[x][y-1])
{
a[x][y-1] = 1;
}
if(!a[x][y+1])
{
a[x][y+1] = 1;
}
}
四、总结
这次的三道题难度不是很高。希望大家可以持之以恒,如果有任何疑问,大家都可以在评论区留言,我看到都会一一回复的!
- 新人创作不易,还望一键三连!感谢!