第十一届蓝桥杯大赛软件类省赛第二场

一、试题A:门牌制作

二、试题B: 既约分数

三、试题C:蛇形填数

四、试题D:跑步锻炼

五、试题E:七段码

六、试题F:成绩统计

七、试题G:回文日期

八、试题H:子串分值和

九、试题I:平面切分

十、试题J:字串排序

一、试题A:门牌制作(5分)

【问题描述】

小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字
符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个
字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

模拟:

代码如下:

//ans = 624
#include<iostream>

using namespace std;

#define ll long long

int ans;

int main(){
	for(int i = 1; i <= 2020; i ++ ){
		int n = i;
		while(n != 0){
			if(n % 10 == 2) ans ++;
			n /= 10;
		}
	}
	cout<<ans;
	return 0;
}

二、试题B: 既约分数(5分)

如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如,34 , 52 , 18 , 71 都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

代码如下:

//ans = 2481215
#include<iostream>

using namespace std;

#define ll long long

int g,ans;

int gcd(int a,int b){
	if(b == 0)
	return a;
	else 
	return gcd(b,a%b);
}
int main(){
	for(int c = 1; c <= 2020; c ++){
		for(int d = 1; d <= 2020; d ++){
			g = gcd(c,d);
			if(g == 1) ans ++;
		}
	}
	cout<<ans;
	return 0;
}

三、试题C:蛇形填数(10分)

【问题描述】
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …

(1)
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列
的数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

方法一:模拟:

// ans = 761
#include<iostream>

using namespace std;

#define ll long long

const int N = 100;

int a[N][N];

int main(){
	int tot = 1,i = 1, j = 1;
	a[i][j] = tot; 
	while(1){
		if(j >= 60) break;
		//往右走一步
		j ++;a[i][j] = ++tot;
		//往斜左走 
		while(j != 1){
			i ++; j --;
			a[i][j] = ++tot;
		}
		//往下走一步
		i++;a[i][j] = ++tot;
		//往斜右走
		while(i != 1){
			j ++; i --;
			a[i][j] = ++tot;
		} 
	}
	for(int i = 1; i <= 20; i ++ ){
		for(int j = 1; j <= 20; j ++ ){
			cout<<a[i][j]<<" ";
		}
		puts("");
	}
	cout<<a[20][20];
	return 0;
}

方法二:

数据范围不大,我们可以手写,但是在我手写的时候,发现对角线上它们之间的差成等差数列,于是发现给出的(20,20)也在对角线上
1 5 13 25 41 61
它们差的公差为d = 4
ans = 前一个数+公差d

代码如下:

#include<iostream>

using namespace std;

#define ll long long

int main(){
	int n = 20;
	int sn = 1 + (n - 1) * (4 + 4 * (n - 1))/2;
	cout<<sn;
	return 0;
}

四、试题D:跑步锻炼

【问题描述】
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了
激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年
10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

日期问题:

  • 模拟

那些算8871的,可能是没判断闰年,注意一下

代码如下:

//ans = 8879
#include<iostream>

using namespace std;

#define ll long long

int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

bool isleap(int n){
	if(n % 400 == 0) return true;
	if(n % 100 != 0 && n % 4 == 0) return true;
	return false;
} 

int main(){
	int y = 2000,m = 1,d = 1,w = 6;
	int cnt = 0;
	while(1){
		if(y == 2020 && m == 10 && d == 2) break;
		if(w == 1 || d == 1) cnt++;
		cnt++,d++,w++;
		if(m == 2){
			if(isleap(y)){
				if(d > 29) m ++, d = 1;
			}else{
				if(d > 28) m ++, d = 1;
			}
		}
		else if(d > days[m]){
			m ++, d = 1;
		}
		if(m > 12){
			y ++, m = 1;
		}
		if(w > 7) w = 1;
	}
	cout<<cnt;	
	return 0;
}

五、试题E:七段码(待补)

六、试题F:成绩统计

在这里插入图片描述
【样例输入】


7
80
92
56
74
88
100
0

【样例输出】

71%
43%

【评测用例规模与约定】
对于 50% 的评测用例,1 ≤ n ≤ 100。
对于所有评测用例,1 ≤ n ≤ 10000。

代码如下:

#include<iostream>

using namespace std;

#define ll long long

double ans1,ans2;
int n,grade;

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		cin >> grade;
		if(grade >= 60) ans1 ++;
		if(grade >= 85) ans2 ++;
	}
	ans1 = ans1 / n * 100; ans2 = ans2 / n * 100;
	printf("%d%%\n",(int)(ans1 + 0.5));
	printf("%d%%\n",(int)(ans2 + 0.5));	
	return 0;
}

七、试题G:回文日期

在这里插入图片描述
【样例输入】

20200202

【样例输出】

20211202
21211212

【评测用例规模与约定】
对于所有评测用例,10000101 ≤ N ≤ 89991231,保证 N 是一个合法日期的
8 位数表示。

代码如下:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

#define ll long long

int n;
bool flag1 = true,flag2 = true;
string res1,res2;

int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

bool isleay(int n) {
	if(n % 400 == 0) return true;
	if(n % 100 != 0 && n % 4 == 0) return true;
	return false;
}

void work(int y,int m,int d) {
	string s1 = "",s2 = "",s3 = "";
	while(y != 0) {
		s1 += y % 10 + '0';
		y /= 10;
	}
	reverse(s1.begin(),s1.end());
	if(m < 10) {
		s2 += '0';
		s2 += m % 10 + '0';
	} else {
		while(m != 0) {
			s2 += m % 10 + '0';
			m /= 10;
		}
		reverse(s2.begin(),s2.end());
	}
	if(d < 10) {
		s3 += '0';
		s3 += d % 10 + '0';
	} else {
		while(d != 0) {
			s3 += d % 10 + '0';
			d /= 10;
		}
		reverse(s3.begin(),s3.end());
	}
	string s = s1 + s2 + s3;
	if(flag1) {
		bool ans1 = true;
		for(int i = 0, j = s.size() - 1; i < s.size()/2; i ++ , j --) {
			if(s[i] != s[j]) ans1 = false;
		}
		if(ans1) flag1 = false,res1 = s;
		
	}
	bool ans2 = false;
	if(s[0] == s[2] && s[2] == s[5] && s[5] == s[7]){
		if(s[1] == s[3] && s[3] == s[4] && s[4] == s[6]){
			ans2 = true;
		}
	}
	if(ans2) flag2 = false,res2 = s;
}
int main() {
	cin >> n;
	int y = n / 10000;
	int m = n % 1000 / 100;
	int d = n % 100;
	while(flag1 || flag2) {
		d ++;
		work(y,m,d);
		if(m == 2) {
			if(isleay(n)) {
				if(d > 29) m ++,d = 1;
			} else {
				if(d > 28) m ++,d = 1;
			}
		} else if(d > days[m]) {
			m ++, d = 1;
		}
		if(m > 12) y ++,m = 1;
	}
	cout<<res1<<endl;
	cout<<res2<<endl;
	return 0;
}

八、试题H:子串分值和(待补)

九、试题I:平面切分(待补)

十、试题J:字串排序(待补)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值