今天是【蓝桥杯】枚举2的6道真题归纳。
一、卡片
2021年A组A题,B组B题。
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。
小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从 1 拼到多少。
例如,当小蓝有 30 张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10,
但是拼 1 时卡片 1 已经只有一张了,不够拼出 11。
现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1 拼到多少?
提示:建议使用计算机编程解决问题。
这题体现了while的优势,当不知道要枚举多大数据时,可以先写个while,找到之后跳出循环就可。要注意的是,while(n)后面如果想继续使用n的话,需要一个临时变量。
这题要注意一个点:1肯定是先用完的。
我们要找的答案是最多可以拼多少个。
即n一定包含1,答案是n-1。
方法一:我的代码
#include<iostream>
using namespace std;
int nums[10];
int main(void)
{
for(int i = 0; i <= 9; i++)
nums[i] = 2021;
int n = 1;
while(1)
{
int res = n;
for(int i = 0; res; i++)
{
nums[res % 10]--;
res /= 10;
}
for(int i = 0; i <= 9; i++)
if(nums[i] < 0)
{
cout<< n-1 << endl;
return 0;
}
n++;
}
return 0;
}
方法二:带练学长的代码
#include<iostream>
using namespace std;
int main(void)
{
int cnt[10];
for(int i = 0; i <= 9; i++)
cnt[i] = 2021;
int n = 1;
while(true)
{
int res = n;
while(res)
{
cnt[res % 10]--;
if(cnt[res % 10] < 0)
{
cout<< n-1 << endl;
return 0;
}
res /= 10;
}
n++;
}
return 0;
}
方法三:老师的代码
#include<iostream>
using namespace std;
int main(void)
{
int cnt[10];
for(int i = 0; i <= 9; i++)
cnt[i] = 2021;
int n = 1;
while(true)
{
int res = n;
while(res)
{
int now = res % 10;
if(cnt[now] > 0)
cnt[now]--;
else
break;
res /= 10;
}
if(res) //while(res)没执行完。
break; //用于跳出双重循环。
n++;
}
cout<< n-1 << endl;
return 0;
}
二、直线
2021年B组C题。
考察:直线的表示,去重统计。
点的结构体表示,map。
#include<bits/stdc++.h>
using namespace std;
struct Point{
double x,y;
}p[23*23];
map<pair<double,double>,int> line;
int main(void)
{
int k = 0;
for(int i = 0; i < 21; i++)
for(int j = 0; j < 20; j++)
{
p[k].x = i;
p[k].y = j;
k++;
}
int cnt = 20 + 21;
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++)
{
if(p[i].x == p[j].x || p[i].y == p[j].y)
continue;
double k = (p[j].y - p[i].y) / (p[j].x - p[i].x);
double b = (p[j].x*p[i].y - p[j].y*p[i].x) / (p[j].x - p[i].x);//p[i].y - k*p[i].x;
if(line[{k,b}] == 0)
{
line[{k,b}] = 1;
cnt++;
}
}
cout<< cnt << endl; //40257
return 0;
}
小补课:unordered_set, unordered_map每次的插入,删除复杂度是O(1)
set,map每次插入,删除是O(longn)。
multiset, multimap头文件是set。可以有重复元素。
#include<iostream>
#include<cstring>
#include<algorithm>
//#include<unordered_set>
#include<set>
using namespace std;
int main(void)
{
int n;
cin>> n;
//unordered_set<string> hash;
set<string> hash;
while(n--)
{
string str;
cin>> str;
hash.insert(str);
}
cout<< endl;
cout<< hash.size() << endl;
for(auto s:hash)
cout<< s << endl;
return 0;
}
c语言实现栈,队列——数组模拟栈,队列。
c++实现栈,队列——如下。
#include<stack>
#include<queue>
stack<int> stack;
queue<int> q;
queue<string> s; //emmm应该是这样
三、回文日期
2020A组F题。
这题,思路好想。是代码量的问题。
写三个函数:回文检验函数,ABABBABA检验函数,有效日期函数。
#include<iostream>
using namespace std;
int num1[105],num2[105],num3[105];
int day[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check_a(int n)
{
int i = 1;
while(n)
{
num1[i] = n % 10;
n /= 10;
i++;
}
if(num1[1]==num1[8] && num1[2]==num1[7] && num1[3]==num1[6] && num1[4]==num1[5])
return true;
return false;
}
bool check_b(int n)
{
int j = 1;
while(n)
{
num2[j] = n % 10;
n /= 10;
j++;
}
if(num2[1]==num2[8] && num2[2]==num2[7] && num2[3]==num2[6] && num2[4]==num2[5])
if(num2[1]==num2[3] && num2[2]== num2[4] && num2[1]!=num2[2])
return true;
return false;
}
//闰年判断函数
bool is_leap(int year)
{
if(year%4 == 0 && year%100 != 0 || year%400 == 0)
return true;
return false;
}
int dayofmonth(int year,int month)
{
if(month == 2)
return is_leap(year)+28;
return day[month];
}
//判断日期是否合法
bool check_c(int n)
{
int year = n / 1000;
int k = 1;
while(n)
{
num3[k] = n % 10;
n /= 10;
k++;
}
int month = num3[4]*10+num3[3];
if(month > 12)
return false;
int day = num3[2]*10 + num3[1];
if(day <= dayofmonth(year,month))
return true;
return false;
}
int main(void)
{
int n;
cin>> n;
int flag = 0;
while(1)
{
n++;
if( !check_c(n) )
continue;
if( check_a(n) && flag == 0 )
{
cout<< n << endl;
flag = 1;
}
if( check_b(n) )
{
cout<< n;
return 0;
}
}
return 0;
}
四、合法日期
题目描述
小蓝正在上小学,老师要求同学们在暑假每天记日记。可是小蓝整个暑假都在玩,直到最后一天才想起要记日记。于是小蓝赶紧编了一些日记交给老师。
没想到,日记很快就被老师发现了问题,原来小蓝记完 8 月 31 日的日记,竟又记了 8 月 32 日和 8 月 33 日的日记。这显然是有问题的,因为根本没有 8 月 32 日和 8 月 33 日。
给定一个月份和一个日期,请问 2021 年有没有这一天。
输入描述
输入的第一行包含一个整数 m,表示月份。
第二行包含一个整数 d,表示日期。
其中,1≤m≤20,1≤d≤40。
输出描述
如果2021年有 m 月 d 日,输入 yes,否则输出 no。
题目明确说明是2021年。2021是平年,即2月有28天。
#include<iostream>
using namespace std;
int day[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(void)
{
int m,d;
cin>> m >> d;
if(d <= day[m])
puts("yes");
else
puts("no");
return 0;
}
五、特别数的和
题目描述
小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。
请问,在 1 到 n 中,所有这样的数的和是多少?
输入格式:
输入一行包含一个整数 n(1≤n≤104 )。
输出描述
输出一行,包含一个整数,表示满足条件的数的和。
写一个check()函数
#include<iostream>
using namespace std;
bool check(int x)
{
while(x)
{
if(x % 10 <= 2 || x % 10 == 9)
return true;
x /= 10;
}
return false;
}
int main(void)
{
int n;
cin>> n;
int sum = 0;
for(int i = 1; i <= n; i++)
if(check(i))
sum += i;
cout<< sum << endl;
return 0;
}
六、猴子分香蕉
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
5 只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
第 1 只猴子醒来,把香蕉均分成 5 堆,还剩下 1 个,就吃掉并把自己的一份藏起来继续睡觉。
第 2 只猴子醒来,把香蕉均分成 5 堆,还剩下 2 个,就吃掉并把自己的一份藏起来继续睡觉。
第 3 只猴子醒来,把香蕉均分成 5 堆,还剩下 3 个,就吃掉并把自己的一份藏起来继续睡觉。
第 4 只猴子醒来,把香蕉均分成 5 堆,还剩下 4 个,就吃掉并把自己的一份藏起来继续睡觉。
第 5 猴子醒来,重新把香蕉均分成 5 堆,哈哈,正好不剩!
请计算一开始最少有多少个香蕉。
#include<iostream>
using namespace std;
bool check(int x)
{
int i;
for(i = 1; i <= 4; i++)
{
if(x == 0 || x % 5 != i)
return false ;
x -= i;
x = x*4/5;
}
if(i == 5)
{
if(x == 0 || x % 5 != 0)
return false;
}
return true;
}
int main(void)
{
int n = 1;
while(1)
{
if(check(n))
{
cout<< n; //3141
return 0;
}
n++;
}
return 0;
}
持续更新,欢迎一起学习!