第十三届蓝桥杯省赛模拟赛C/C++

第一题:

问题描述

以下是一个 25 行 25 列的字母矩阵,全部由字母 A 和 B 组成。

AAAAAAABABBAABABABAAAAAAA

ABBBBBABBAABBBBBABABBBBBA

ABAAABABBBABAABBBBABAAABA

ABAAABABBBBBAABAABABAAABA

ABAAABABBABABBABABABAAABA

ABBBBBABBBABAABBBBABBBBBA

AAAAAAABABABABABABAAAAAAA

BBBBBBBBABAABABBBBBBBBBBB

AABAABABBAAABBAAABABBBBBA

ABBABABBBABBAAAABBBBAAAAB

BBBBAAABABAABABAABBBAABBA

BBAABABABAAAABBBAABBAAAAA

ABABBBABAABAABABABABBBBBA

AAAABBBBBABBBBAAABBBABBAB

AABAABAAABAAABAABABABAAAA

ABBBBBBBBABABBBBABAABBABA

ABBBAAABAAABBBAAAAAAABAAB

BBBBBBBBABBAAABAABBBABBAB

AAAAAAABBAAABBBBABABAABBA

ABBBBBABBAABABAAABBBABBAA

ABAAABABABBBAAAAAAAAAABAA

ABAAABABABABBBABBAABBABAA

ABAAABABBABBABABAABAABAAA

ABBBBBABABBBBBABBAAAABAAA

AAAAAAABAABBBAABABABBABBA

请问在这个矩阵中有多少个字母A?

#include
#define ll long long
using namespace std;
char s[625];
void solve() {
	cin >> s;
	ll ans = 0;
	for (int i = 0; i < 625; i++) {
		if (s[i] == 'A') ans++;
	}
	cout << ans;
}
int main() {
	solve();
    return 0;
}

打开txt文本将题目中的回车全删了读取一下输出答案

如果一个整数的某个数位包含 2 ,则称这个数为一个“最2数字”。例如:102、2021 都是最2数字。

请问在 1(含) 到 2021(含) 中,有多少个最2数字。

#include
#define ll long long
using namespace std;
bool zui2(int a) {
	while(a) {
		int t = a % 10;
		a /= 10;
		if (t == 2) return true;
	}
	return false;
}
void solve() {
	int ans = 0;
	for (int i = 1; i <= 2021; i++) {
		if (zui2(i)) ans++;
	} 
	cout << ans;
}
int main() {
	solve();
    return 0;
}

第三题:

问题描述

有一个整数 A=2021,每一次,可以将这个数加 1 、减 1 或除以 2,其中除以 2 必须在数是偶数的时候才允许。

例如,2021 经过一次操作可以变成 2020、2022。

再如,2022 经过一次操作可以变成 2021、2023 或 1011。

请问,2021 最少经过多少次操作可以变成 1。

是偶数就除2,奇数就-1.

#include
#define ll long long
using namespace std;
void solve() {
	int a = 2021;
	int ans = 0;
	while(a != 1) {
		if (a & 1) a--, ans++, cout << a << endl;
		else {
			a /= 2;
			ans++;
			cout << a << endl;
		}
	} 
	cout << ans;
}
int main() {
	solve();
    return 0;
}

第四题:

问题描述

对于一个 n 行 m 列的表格,我们可以使用螺旋的方式给表格依次填上正整数,我们称填好的表格为一个螺旋矩阵。

例如,一个 4 行 5 列的螺旋矩阵如下:

1 2 3 4 5

14 15 16 17 6

13 20 19 18 7

12 11 10 9 8

请问,一个 30 行 30 列的螺旋矩阵,第 20 行第 20 列的值是多少?

螺旋矩阵的打印,如果不会代码可以用excel打表哈哈哈。

ans:819

#include
#define ll long long
using namespace std;
int dp[200][200];
void solve(int n) {
	int loop = n / 2;
	int mid = n / 2;
	int offset = 1;
	int k = 1;
	int startx = 0, starty = 0;
	while (loop--) {
		int i = startx;
		int j = starty;
		for (j = starty; j < starty + n - offset ; j++) {
			dp[startx][j] = k++;
		}
		for (i = startx; i < n - offset + startx; i++) {
			dp[i][j] = k++;
		}
		for (; j > starty; j--) {
			dp[i][j] = k++;
		}
		for (; i > startx; i--) {
			dp[i][j] = k++;
		}
		offset += 2;
		startx++, starty++;
	}
	if (n & 1) dp[mid][mid] = n * n;
	for (int i = 0;i

第五题:

问题描述

一棵二叉树有2021个结点。该树满足任意结点的左子树结点个数和右子树的结点个数之差最多为1。

定义根结点的深度为0,子结点的深度比父结点深度多1。

请问,树中深度最大的结点的深度最大可能是多少?

依题意得这颗二叉树为向完全二叉树靠拢,按照完全二叉树的公式,深度为k的二叉树结点个数为 2^k - 1;

2^11 = 2048,  2^10 = 1024;  简单画一下三个节点的二叉树 2^2  - 1= 3,深度为1(因为根节点深度为0)

所以答案深度为 11-1 = 10

第六题:

问题描述

一个和尚要挑水,每次最多能挑 a 千克,水缸最多能装 t 千克,开始时水缸为空。

请问这个和尚最少要挑多少次可以将水缸装满?

输入格式

输入一行包含两个整数 a, t,用一个空格分隔。

输出格式

输出一行包含一个整数,表示答案。

样例输入

20 2021

样例输出

102

评测用例规模与约定

对于所有评测用例,1 <= a <= 100,1 <= t <= 10000。

简单模拟 注意n为奇数时要+1

#include
#define ll long long
using namespace std;
int a, t;
void solve() {
	cin >> a >> t;
	int ans = t / a;
	if (t % a != 0) {
		ans++;
	} 
	cout << ans;
}
int main() {
	solve();
    return 0;
}

第七题:

问题描述

在金融领域,通常将金额的百位和千位之间、十万位和百万位之间增加逗号(千分位分隔符),以方便阅读。一般从个位开始,每三位之前增加一个逗号。

例如:1234567890.00 通常写成 1,234,567,890.00。

注意小数点后固定保留 2 位。

给定一个包含千分位分隔符的数值,请读入后输出对应的不含千分位的数值,小数点仍然保留 2 位。

输入格式

输入一行包含一个由千分位分隔符的数值,恰好有 2 位小数。

输出格式

输出不含千分位分隔符的数值,保留 2 位小数。

样例输入

1,234,567,890.00

样例输出

1234567890.00

评测用例规模与约定

对于所有评测用例,给定的数值整数部分不超过12位。

思路:以字符串形式输入,删除所有的逗号就行了。

#include
#define ll long long
using namespace std;
string s; 
void solve() {
	cin >> s;
	while(s.find(',') != string::npos) {
		int pos = s.find(',');
		s.erase(pos, 1);
	}
	//s.erase(3, 1);
	cout << s; 
}
int main() {
	solve();
    return 0;
}

第八题:

问题描述

小蓝有一个插板,形状用一个 n * m 的01矩阵表示,0 表示板面,1 表示插孔。

小蓝还有一个插头,形状用一个 r * c 的01矩阵表示,0 表示没有伸出的部分,1 表示伸出的部分。插头伸出的部分必须插在插孔里面。

为了安全,插头插到面板上不能有任何部分超过插板边界(包括没有伸出的部分)。

插头和插板都不能旋转,也不能翻转。请求出插头插入插板的合理位置。

输入格式

输入的第一行包含两个整数 n, m。

接下来 n 行,每行一个长度为 m 的01串,表示插板的形状。

接下来一行包含两个整数 r, c。

接下来 r 行,每行一个长度为 c 的01串,表示插头的形状。

输出格式

如果插头没办法安全插入插板中,输出“NO”。否则输出两个数 a, b,表示插头的第 1 行第 1 列对应插板的第 a 行第 b 列。如果有多种情况满足要求,输出 a 最小的方案,如果 a 最小的方案有多个,输出在 a 最小的前提下 b 最小的方案。

样例输入

3 4

0110

0000

0000

3 3

000

010

000

样例输出

NO

样例说明

在插头不超出范围的前提下无法插入。

样例输入

4 7

1110100

1101111

0001111

0000011

2 3

111

011

样例输出

2 4

评测用例规模与约定

对于 50% 的评测用例,2 <= n, m, r, c <= 20。

对于所有评测用例,2 <= n, m, r, c <= 100。

注意边界然后模拟。。。每次取到一个 ’1‘ 然后比对

#include
#define ll long long
using namespace std;
int n, m, r,c;
string chazuo[101];
string chatou[101];
int pipei;
bool check(int posx, int posy, int x, int y) {
	//cout << endl;
	int cnt = 0;
	int k = posx;
	int l = posy;
	if (m - posy < c || n - posx + 1 < r) return false;
	for (int i = x; i < r; i++) {
		for (int j = y; j < c ;j++) {
			if (chazuo[k][l]=='1' && chatou[i][j] == '1') {
				l++;
				cnt++;
			}
			else if (chatou[i][j] == '0') {
				l++;
			}
			else if (chatou[i][j] == '1' && chazuo[k][l] == '0') return false;
			if (cnt == pipei) {
				return true;
			}
			//cout << i << " 插头 " << j << "    " << k << " 插座 " << l - 1 << "  计数" << cnt << endl;  
		}
		k++;
		l = posy;
	}
	return false;
}
void solve() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> chazuo[i];
	}
	cin >> r >> c;
	for (int i = 0; i < r; i++) {
		cin >> chatou[i];
	}
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (chatou[i][j] == '1') pipei++;
		}
	}
	//cout << check(0, 0, 0, 0) << endl;
	int gapRow = n - r;
	int gapCol = m - c;
	if (gapRow < 0 || gapCol < 0) {
		cout << "NO";
		return;
	}
	int first_OnechatouX;
	int first_OnechatouY;
	//string first;
	for (int i = 0; i < r; i++) {
		if (chatou[i].find('1') != string::npos) {
			first_OnechatouX = i;
			first_OnechatouY = chatou[i].find('1');
			//first = chatou[i].substr()
			break;
		}
	}	
	//printf("%d,%d  %d\n", first_OnechatouX, first_OnechatouY, pipei);
	for (int i = 0; i < n; i++) {
		if (first_OnechatouX > i) continue;
		for (int j = 0; j < m; j++) {
			if (chazuo[i][j] == '1') {
				if (check(i, j, first_OnechatouX, first_OnechatouY)) {
					cout << i + 1 << " " << j + 1;
					return;
				}
			}
		}
	}
	cout << "NO";
	return;
}
int main() {
	solve();
	//system("pause");
    return 0;
}

第九题:

问题描述

给定正整数 a, b, c,请问有多少个正整数,是其中至少两个数的约数。

输入格式

输入一行包含三个正整数 a, b, c。

输出格式

输出一行包含一个整数,表示答案。

样例输入

30 70 35

样例输出

6

样例说明

1、2、5、7、10、35满足条件。

评测用例规模与约定

对于 50% 的评测用例,1 <= a, b, c <= 1000000。

对于所有评测用例,a, b, c 不超过 10**12(10的12次方)。

按照题意,用暴力捞点分。。。。

#include
#define ll unsigned long long
using namespace std;
ll a, b, c;
ll ans;
map m;
void solve() {
	//ll ans = 0;
	cin >> a >> b >> c;
	ll ta = a, tb = b, tc = c; 
	ll Max = max(a, b);
	for (int i = 1; i <= Max; i++) {
		if (ta % i == 0 && tb % i == 0 && m[i] == 0) {
			
			m[i] = 1,ans++;;
			//m[i] = 1;
			//cout << i << " ";
			//ta /= i; tb /= i;
		}
	}
	Max = max(a, c);
	ta = a;
	for (int i =1; i <= Max; i++) {
		if (ta % i == 0 && tc % i == 0&& m[i] == 0) {
			
			m[i] = 1,ans++;;
			//m[i] = 1;
			//cout << i << " ";
			//ta /= i; tc /= i;
		}
	}
	tc = c;
	for (int i =1; i <= Max; i++) {
		if (tc % i == 0 && tb % i == 0&& m[i] == 0) {
			
			m[i] = 1, ans++;;
			//m[i] = 1;
			//cout << i << " ";
			//tb /= i; tc /= i;
		}
	}
	cout <

第十题不会

第十题:

问题描述

小蓝很喜欢玩汉诺塔游戏。

游戏中有三根柱子,开始时第一根柱子上有 n 个圆盘,从上到下圆盘的大小依次为 1 到 n。

每次,可以将一个盘子从一根柱子上移动到另一根柱子上,这个盘子必须是柱子最上方的盘子,而且移到的柱子上的盘子必须比这个盘子大。

小蓝的目标是将所有的盘子移动到第三根柱子上。

汉诺塔是个经典问题,当盘子数量为 n 时,最少需要移动 2**n-1 步,其中 2**n 表示 2 的 n 次方。

小蓝已经玩了一会儿(不一定按最优方案玩),他想知道,对于他目前的局面,最少还需要多少步可以到达目标。

输入格式

输入的第一行包含三个非负整数 a, b, c,分别表示目前每根柱子上的盘子数。在本题中,n=a+b+c。

第二行包含 a 个整数,相邻的整数之间使用一个空格分隔,表示第一根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。

第三行包含 b 个整数,相邻的整数之间使用一个空格分隔,表示第二根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。

第四行包含 c 个整数,相邻的整数之间使用一个空格分隔,表示第三根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。

输出格式

输出一行包含一个整数,表示答案。

样例输入

1 2 3

1

2 3

4 5 6

样例输出

7

评测用例规模与约定

对于 30% 的评测用例,2 <= n <= 5。

对于所有评测用例,2 <= n <= 60。

你可能感兴趣的:(蓝桥杯,c++)