今天是【蓝桥杯】枚举的6道练习题。
一、门牌制作
题目描述
门牌制作20
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 00 到 99 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
我在写这道题的时候,没有写13行。14行写的是while(i),内层循环i值的更新改变了外层循环i的值,进入了死循环。要注意这一点。
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
int main(void)
{
int cnt = 0;
int res;
for(int i = 2; i <= 2020; i++)
{
int n = i; //注意这里
while(n)
{
res = n % 10;
if(res == 2)
cnt++;
n /= 10;
}
}
cout<< cnt << endl;
return 0;
}
二、顺子日期
顺子日期21
问题描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022 年份中,一共有多少个顺子日期?
法一:直接手推。分别是,0120~0129共十个,1012,1123,1230,1231。
法二:枚举。
更新中……
三、货物摆放
货物摆放22
题目描述
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足 n = L×W×H。
给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1。
请问,当 n = 2021041820210418(注意有 16位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
中间输出pos发现2021041820210418只有128个因子。因此const int N = 1e3+10;就足够了。平时遇到的数,它们的因子数也没有很多。你看,2021041820210418这么大的数因子也才只有128个嘛~
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 1e3+10;
LL yinzi[N];
int main(void)
{
int pos = 0;
LL n = 2021041820210418;
for(LL i = 1; i*i <= n; i++) //
if(n % i == 0)
{
yinzi[pos++] = i;
if(i != n/i)
yinzi[pos++] = n/i;
}
LL ans = 0;
for(LL j = 0; j < pos; j++ )
{
for(LL k = 0; k < pos; k++)
{
if(yinzi[j] * yinzi[k] > n) continue;
for(LL l = 0; l < pos; l++)
{
if(yinzi[j] * yinzi[k] * yinzi[l] == n)
ans++;
}
}
}
cout<< ans << endl;
return 0;
}
四、质数
质数23
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
我们知道第一个质数是 2、第二个质数是 3、第三个质数是 5……
请你计算第 2019个质数是多少?
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
bool is_prime(int x) //写一个判断质数的函数
{
for(int i = 2; i <= x/2; i++)
if(x % i == 0)
return false;
return true;
}
int main(void)
{
int cnt = 0,res; //cnt计有几个质数,res是一个临时变量。
int i = 2;
while(cnt != 2019)
{
if(is_prime(i))
cnt++;
res = i++;
}
cout<< res << endl;
return 0;
}
五、数的分解
数的分解24
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?
注意交换 3 个整数的顺序被视为同一种方法,例如1000+1001+18和1001+1000+18 被视为同一种。
#include<iostream>
using namespace std;
bool check(int x) //检验一个数的各位有没有2,4
{
int c;
while(x)
{
c = x%10;
if(c == 2 || c == 4)
return true; //如果有2,4返回1
x /= 10;
}
return false;
}
int main(void)
{
int cnt = 0;
for(int i = 1; i <= 673; i++) // i <= 2019也行
{
for(int j = i+1; j <= (2019-i)/2; j++) // j <= 2019也行
{
if(i >= j || i >= 2019-i-j || j >= 2019-i-j) continue;
int res = check(i) + check(j) + check(2019-i-j);
if(res == 0)
cnt++;
}
}
cout<< cnt << endl;
return 0;
}
六、赢球票
赢球票25
题目描述
某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。
主持人拿出 N 张卡片(上面写着1⋯N 的数字),打乱顺序,排成一个圆圈。你可以从任意一张卡片开始顺时针数数: 1,2,3 ⋯如果数到的数字刚好和卡片上的数字相同,则把该卡片收入囊中,从下一个卡片重新数数。直到再无法收获任何卡片,游戏结束。囊中卡片数字的和就是赢得球票的张数。
比如:卡片排列是:1 2 3。
我们从 1 号卡开始数,就把 1 号卡拿走。再从 2 号卡开始,但数的数字无法与卡片对上,很快数字越来越大,不可能再拿走卡片了。因此这次我们只赢得了 1 张球票。
还不算太坏!如果我们开始就傻傻地从 2 或 3 号卡片数起,那就一张卡片都拿不到了。
如果运气好,卡片排列是 2 1 3,那我们可以顺利拿到所有的卡片!
本题的目标:已知顺时针卡片序列,随便你从哪里开始数,求最多能赢多少张球票(就是收入囊中的卡片数字之和)
输入描述
第一行一个整数 N(N≤100),表示卡片数目。
第二行N 个整数,表示顺时针排列的卡片。
输出描述
输出一行,一个整数,表示最好情况下能赢得多少张球票。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2 + 10;
int n;
int a[N], backup[N];
int get(int k)
{
memcpy(a, backup, sizeof a);
int sum = 0, len = 1;
while (true)
{
while (a[k] == 0)
k = (k + 1) % n;
if (a[k] == len)
{
sum += a[k];
a[k] = 0;
len = 1;
if (*max_element(a, a + n) == 0)
return sum;
}
else
len ++;
k = (k + 1) % n;
if (len > n)
return sum;
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
cin >> backup[i];
int res = 0;
for (int i = 0; i < n; i ++ )
res = max(res, get(i));
cout << res << endl;
return 0;
}
持续更新,欢迎一起学习~