蓝桥杯2020初赛

一、[蓝桥杯2020初赛] 门牌制作

小蓝要为一条街的住户制作门牌号。
这条街一共有2020 位住户,门牌号从1 到2020 编号。
小蓝制作门牌的方法是先制作0 到9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017 需要依次粘贴字符1、0、1、7,即需要1 个字符0,2 个字符1,1 个字符7。
请问要制作所有的1 到2020 号门牌,总共需要多少个字符2?

#include<iostream>
using namespace std;
int main()
{
	int ans=0;
	for (int i = 1; i <= 2020; i++)
	{
		int k = i;
		while (k)
		{
			if (k % 10 == 2)
			{
				ans++;
			}
			k /= 10;
		}
	}
	cout << ans;
}

二、[蓝桥杯2020初赛] 既约分数

如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。
例如3/4,5/2,1/8,7/1都是既约分数。
请问,有多少个既约分数,分子和分母都是1 到2020 之间的整数(包括1和2020)?

#include<iostream>
using namespace std;
int gcd(int i, int j)
{
	return j == 0 ? i : gcd(j, i % j);
}
int main() 
{
	int ans=0;
	for (int i = 1; i <= 2020; i++)
	{
		for (int j = 1; j <= 2020; j++)
		{
			if (gcd(i, j) == 1)ans++;
		}
	}
	cout << ans;
	return 0;
}

三、蛇形填数

如下图所示,小明用从1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15...

3 5 8 14...

4 9 13...

10 12...

11...... 
容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20 行第20 列的数是多少?

#include<iostream>
using namespace std;
int main()
{
	int a[100][100];
	int z=1;
	for (int i = 2; i <= 40; i++)
	{
		if (i % 2 == 0)
		{
			int k = i;
			int j = i - 1;
			int p = 1;
			while (--k)
			{
				a[j--][p++]=z;
				z++;
			}
		}
		else
		{
			int k = i;
			int j = i - 1;
			int p = 1;
			while (--k)
			{
				a[p++][j--] = z;
				z++;
			}
		}
	}
	printf("%d", a[20][20]);
}

四、[蓝桥杯2020初赛] 七段码

小蓝要用七段码数码管来表示一种特殊的文字。


上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10;
int b[N][N];
bool st[N];
int p[N];
int find(int x)
{
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}
int main()
{

	b[1][2] = b[1][6] = 1;
	b[2][1] = b[2][7] = b[2][3] = 1;
	b[3][2] = b[3][7] = b[3][4] = 1;
	b[4][3] = b[4][5] = 1;
	b[5][4] = b[5][7] = b[5][6] = 1;
	b[6][1] = b[6][7] = b[6][5] = 1;
	b[7][2] = b[7][3] = b[7][5] = b[7][6] = 1;

	int ans = 0;
	for (int i = 1; i < 1 << 7; i++)
	{
		memset(st, 0, sizeof st);
		for (int j = 1; j <= 7; j++)p[j] = j;

		for (int j = 0; j < 7; j++)
			if ((i >> j) & 1)st[j + 1] = true;

		for (int k = 1; k <= 7; k++)
			for (int j = 1; j <= 7; j++)
				if (b[k][j] && st[k] && st[j])
				{
					int pk = find(k);
					int pj = find(j);
					if (pk != pj)
						p[pk] = pj;
				}
		int cnt = 0;
		for (int j = 1; j <= 7; j++)
			if (st[j] && p[j] == j)cnt++;


		if (cnt == 1)ans++;
	}

	cout << ans;

}

五、[蓝桥杯2020初赛] 跑步锻炼

小蓝每天都锻炼身体。
正常情况下,小蓝每天跑1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑2 千米。如果同时是周一或月初,小蓝也是跑2 千米。
小蓝跑步已经坚持了很长时间,从2000 年1 月1 日周六(含)到2020 年10 月1 日周四(含)。
请问这段时间小蓝总共跑步多少千米?

这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int ans = 0, num;
int fun(int i)
{
	if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)return 1; 
	return 0;
}
int a[15] = {0,31, 28,31, 30,31, 30,31, 31,30,31,30, 31,};
int main()
{
	for (int i = 2000; i <= 2021; i++)
	{
		if (fun(i))a[2] = 29;
		else a[2] = 28;
		for (int j = 1; j <= 12; j++)
			for (int k = 1; k <= a[j]; k++)
			{
				ans += 1;
				if (k == 1 || num % 7 == 2)ans++;
					num++;
				if (i == 2020 && j == 10 && k == 1)
				{
					cout << ans;
					return 0;
				}
			}
	}
	return 0;
}

六、 [蓝桥杯2020初赛] 回文日期

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年2 月2日。因为如果将这个日期按“yyyymmdd” 的格式写成一个8 位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示20200202 是“千年一遇” 的特殊日子。对此小明很不认同,因为不到2 年之后就是下一个回文日期:20211202 即2021 年12 月2 日。
也有人表示20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同,因为大约100 年后就能遇到下一个ABABBABA 型的回文日期:21211212 即2121 年12 月12 日。算不上“千年一遇”,顶多算“千年两遇”。
给定一个8 位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA 型的回文日期各是哪一天。

输入格式

输入包含多组测试数据,第一行为正整数T。(T≤1000)
接下来T行,每行包含一个八位整数N,表示日期。
对于所有评测用例,10000101 ≤ N ≤ 89991231,保证N 是一个合法日期的8 位数表示。

#include<iostream>
using namespace std;
int main()
{
	int T;
	cin >> T;
	int k[8];
	int m[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	while (T--)
	{
		int a;
		cin >> a;
		int l1=0,l2=0;
		int v1 = 0, v2 = 0;
		for (int i = a+1;; i++)
		{
			if ((i / 100) % 100 <= 12)
			{
				if (i % 100 <= m[(i / 100) % 100] || i % 100 >= 1)
				{
					int j = 0;
					int z = i;
					while (z)
					{
						k[j] = z % 10;
						j++;
						z /= 10;
					}
					bool flag1 = true;
					bool flag2 = false;

					for (int m = 0; m < 8; m++)
					{
						if (k[m] != k[7 - m])
						{
							flag1 = false;
							break;
						}
					}
					if (flag1 && !v1)
					{
						cout << i << endl;
						v1 = 1;
					}
					if (flag1 && k[0] == k[2] && k[1] == k[3])flag2 = true;
					if (flag2 && !v2)
					{
						cout << i << endl;
						v2 = 1;
					}
					if (v1 && v2)break;
				}
				else i = ((i / 100) + 1) * 100;
			}
				else i = ((i / 10000) + 1) * 10000;
		}
	}
	return 0;
}

七、[蓝桥杯2020初赛] 字串排序

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串lan 排序,只需要1 次交换。对于字符串qiao 排序,总共需要4 次交换。
小蓝的幸运数字是V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V 次交换。请帮助小蓝找一个这样的字符串。
如果可能找到多个,请告诉小蓝最短的那个。
如果最短的仍然有多个,请告诉小蓝字典序最小的那个。
请注意字符串中可以包含相同的字符。

输入第一行为T,表示存在T组测试数据。(T≤25)
对于每组测试数据,输入一行包含一个整数V,为小蓝的幸运数字。
对于所有评测用例,1 ≤ V ≤ 10000。

:不会

八、[蓝桥杯2020初赛] 成绩统计

小蓝给学生们组织了一场考试,卷面总分为100 分,每个学生的得分都是一个0 到100 的整数。
如果得分至少是60 分,则称为及格。如果得分至少为85 分,则称为优秀。
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。

输入的第一行包含一个整数n,表示考试人数。
接下来n 行,每行包含一个0 至100 的整数,表示一个学生的得分。

输入的第一行包含一个整数n,表示考试人数。
接下来n 行,每行包含一个0 至100 的整数,表示一个学生的得分。

#include<iostream>
using namespace std;
int main()
{
	int T;
	cin >> T;
	int num = T;
	float ex=0, ji=0;
	while (T--)
	{
		int a;
		cin >> a;
		if (a >= 85)ex++;
		if (a >= 60)ji++;
	}
	float jii, exi;
	int k = (ji / num) * 1000;
	int p = (ex / num) * 1000;
	if (k % 10 >= 5)k = (k / 10) + 1;
	else k = k / 10;
	if (p % 10 >= 5)p = (p / 10) + 1;
	else p = p / 10;
	cout << k << '%' <<endl<< p << '%';
}

九、[蓝桥杯2020初赛] 子串分值和

对于一个字符串S ,我们定义S 的分值f (S ) 为S 中出现的不同的字符个数。
例如f (”aba”) = 2, f (”abc”) = 3, f (”aaa”) = 1。
现在给定一个字符串S [0 : n - 1](长度为n),请你计算对于所有S 的非空子串S [i : j](0 ≤ i ≤ j < n), f (S [i:: j]) 的和是多少。

输入一行包含一个由小写字母组成的字符串S 。
对于所有评测用例,1 ≤ n ≤ 100000。

输出一个整数表示答案。

#include<iostream>
using namespace std;
typedef long long LL;
int l[500];
int main()
{
	string s;
	cin >> s;
	int n = s.size();
	s = ' ' + s;
	LL ans = 0;
	for (int i = 1; i <= n; i++)
	{
		ans += (LL)(i - l[s[i]]) * (n - i + 1);
		l[s[i]] = i;
	}
	cout << ans << endl;
	return 0;
}

十、[蓝桥杯2020初赛] 平面切分

平面上有N 条直线,其中第i 条直线是y = Ai * x + Bi。
请计算这些直线将平面分成了几个部分。

第一行包含一个整数N。
以下N 行,每行包含两个整数Ai, Bi。
对于50% 的评测用例,1 ≤ N ≤ 4, -10 ≤ Ai, Bi ≤ 10。
对于所有评测用例,1 ≤ N ≤ 1000, -100000 ≤ Ai, Bi ≤ 100000。

#include<iostream>
#include<map>
#include<set>
using namespace std;
set<pair<double, double> > line;
int n;
int ans = 1;
double x, y;
void compute(double a, double b) {
	double c, d;
	pair<double, double> inter;
	set<pair<double, double> > point;
	for (auto it : line) {
		c = it.first, d = it.second;
		if (c != a) {

			inter.first = (d - b) / (a - c);
			inter.second = a*inter.first + b;

			point.insert(inter);
		}

	}
	ans += point.size();
	point.clear();
}
int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> x >> y;
		int l = line.size();
		line.insert(make_pair(x, y));
		
		if (line.size() != l) 
        {
			ans++;
			compute(x, y);
		}
	}
	cout << ans;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值