蓝桥杯2019年省赛C/C++大学B组

1. 组队

蓝桥杯2019年省赛C/C++大学B组_第1张图片
蓝桥杯2019年省赛C/C++大学B组_第2张图片
答案是490

2. 年号字串

蓝桥杯2019年省赛C/C++大学B组_第3张图片
思路类似于转换26进制,但是这里不存在0。
代码

#include
#include
#include
#include
using namespace std;
char ans[10];
int main(){
	ans[0] = 'A';
	for(int i = 2; i <= 2019; i++){
		if(ans[0] == 'Z'){
			if(ans[1] == '\0') ans[1] = 'A';
			else if(ans[1] == 'Z'){
				if(ans[2] == '\0') ans[2] = 'A';
				else ans[2]++;
				ans[1] = 'A';
			}
			else ans[1]++;
			
			ans[0] = 'A';	
		}
		else ans[0]++;
		reverse(ans, ans + strlen(ans));
		cout << ans << endl;
		reverse(ans, ans + strlen(ans));
	}
	reverse(ans, ans + strlen(ans));
	cout << ans << endl;
	return 0;
}

3. 数列求和

蓝桥杯2019年省赛C/C++大学B组_第4张图片
答案 4659

#include
#include
#include
#include
using namespace std;
const int mod = 10000;
int a, b, c, d;
int main(){
	b = 1;
	c = 1;
	d = 3;
	for(int i = 5; i <= 20190324; i++){
		a = b + c + d;
		b = c % mod;
		c = d % mod;
		d = a % mod;
		a = a % mod;
	}
	cout << a << endl;
	return 0;
}

4. 数的分解
蓝桥杯2019年省赛C/C++大学B组_第5张图片
答案 40785
思路 直接枚举, 时间复杂度是9次方,大概10秒可以算出来,完全没问题,因为存在重复abc, acb, cab, cba, bac, bca,结果除以6就可以了

#include
#include
#include
#include
using namespace std;
int ans;
bool check(int n){
	while(n){
		if(n % 10 == 2 || n % 10 == 4) return false;
		n /= 10;
	}
	return true;
}
int main(){
	for(int i = 1; i < 2019; i++)
		for(int j = 1; j < 2019; j++)
			for(int k = 1; k < 2019; k++){
				if(i + j + k == 2019){
					if(check(i) && check(j) && check(k)){
						if(i != j && i != k && j != k)ans++;
					}
				}
			}
	cout << ans / 6 << endl;
	return 0;
}

5. 迷宫
蓝桥杯2019年省赛C/C++大学B组_第6张图片
思路 用bfs, 结构体内存下路径,每次按照最小的字典序走,第一次走到终点对应的路径就是最小的字典序。
答案 DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
代码

#include
#include
#include
#include
#include
using namespace std;
const int n = 30, m = 50;
struct node{
	int x, y, sum;
	char p[500];
};
char map[35][55];
bool vis[35][55];
char path[200];
int dx[] = {1, 0, 0, -1};
int dy[] = {0, -1, 1, 0};
char p[] = {'D', 'L', 'R', 'U'};
void bfs(){
	queue<node> q;
	q.push({1, 1, 1});
	while(q.size()){
		node t = q.front();
		q.pop();
		int x = t.x;
		int y = t.y;
		int s = t.sum;
		if(vis[x][y]) continue;
		vis[x][y] = true;
		for(int i = 0; i < 4; i++){
			int fx = x + dx[i];
			int fy = y + dy[i];
			if(fx > 0 && fx <= n && fy > 0 && fy <= m && map[fx][fy] == '0' && !vis[fx][fy]){
				t.p[s] = p[i];
		 		 if(fx == n && fy == m){
					for(int i = 1; i <= s; i++) cout << t.p[i];
					cout << s << endl;
				}
				node te;
				te.x = fx, te.y = fy, te.sum = s + 1;
				memcpy(te.p, t.p, sizeof t.p);
				q.push(te);
			}
		}
	}
}
int main(){
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++) 
			cin >> map[i][j];
	bfs();
	return 0;
}

6. 特别数的和
蓝桥杯2019年省赛C/C++大学B组_第7张图片
思路
直接暴力,数据最大是10000,所以运算最大也是40000,题目给了1s,所以应该是可以过的

#include
#include
#include
#include
using namespace std;
int ans;
bool check(int n){
	while(n){
		if(n % 10 == 2 || n % 10 == 0 || n % 10 == 1 || n % 10 == 9)
		return true;
		n /= 10;
	}
	return false;
}
int n;
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		if(check(i)) ans += i;
	}
	printf("%d\n", ans);
	return 0;
}

7. 完全二叉树的权值
蓝桥杯2019年省赛C/C++大学B组_第8张图片蓝桥杯2019年省赛C/C++大学B组_第9张图片
思路
就把每层的存起来,遍历一遍找到最大值。

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
ll sum[20];
int a, n;
int getdeep(int n){
	int ans = 0;
	while(n){
		ans++;
		n /= 2;
	}
	return ans;
} 
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d", &a);
		sum[getdeep(i)] += a;
	}
	ll ans = -0x3f3f3f3f;
	int deep;
	for(int i = 1; i <= 18; i++){
		if(sum[i] > ans){
			deep = i;
			ans = sum[i];
		}
	}
	printf("%d\n", deep);
	return 0;
}

8. 等差数列
蓝桥杯2019年省赛C/C++大学B组_第10张图片
思路
等差数列的公差就是给出数列的所有的差的最大公约数

#include
#include
#include
#include
#include
using namespace std;
const int N = 100010;
bool vis[N];
int a[N], b;
int n;
int cnt;
int gcd(int a, int b){
	if(b == 0) return a;
	return gcd(b, a % b);
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d", &b);
		if(vis[b]) continue;
		vis[b] = true;
		a[cnt++] = b;
	}
	n = cnt;
	sort(a, a + n);
	b = a[1] - a[0];
	for(int i = 2; i < n; i++){
		int x = a[i] - a[1];
		b = gcd(x, b);
	}
	b = (a[n - 1] - a[0]) / b + 1;
	printf("%d\n", b);
	return 0;
}

9. 后缀表达式

蓝桥杯2019年省赛C/C++大学B组_第11张图片
这道题比较有争议,我用的贪心,有m个减号,就相当于把m个负数变成正数,如果负数不足m个,就把最小的那几个数变成负数,然后相加。

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N = 100010;
int a[N];
int n, m;
bool cmp(int a, int b){
	return abs(a) > abs(b);
}
int main(){
	scanf("%d%d", &n, &m);
	int s = n + m + 1;
	for(int i = 0; i < s; i++){
		scanf("%d", a + i);
	}
	sort(a, a + s, cmp);
	for(int i = 0; i < s && m > 0; i++)
		if(a[i] < 0) m--, a[i] = -a[i];
	if(m > 0){
		for(int i = s - 1; i >= 0 && m > 0; i--){
			a[i] = -a[i];
			m--;
		}
	}
	ll ans = 0;
	for(int i = 0; i < s; i++){
		ans += a[i];
		cout << a[i] << " ";
	}
	cout << endl;
	printf("%lld\n", ans);
	return 0;
}

10. 灵能传输

蓝桥杯2019年省赛C/C++大学B组_第12张图片
蓝桥杯2019年省赛C/C++大学B组_第13张图片
蓝桥杯2019年省赛C/C++大学B组_第14张图片
思路
当三个数同号时,不需要操作,,需要操作的时候必须满足一下情况,flag记录还有没有满足交换的情况,有就继续遍历,没有就退出循环。
蓝桥杯2019年省赛C/C++大学B组_第15张图片

#include
#include
#include
#include
using namespace std;
const int N = 10010;
int a[N];
int n, t;
bool dif(int a, int b){
		if(a > 0 && b < 0) return true;
		if(a < 0 && b > 0) return true;
		return false;
}
bool Same(int x, int y){
	if(x > 0 && y > 0) return true;
	if(x < 0 && y < 0) return true;
	return false;
}
void sove(int i){
	a[i - 1] += a[i];
	a[i + 1] += a[i];
	a[i] -= 2 * a[i];
}
int main(){
	scanf("%d", &t);
	while(t--){
		scanf("%d", &n);
		bool zheng = false, fu = false;
		for(int i = 1; i <= n; i++){
			scanf("%d", a + i);
			if(a[i] > 0) zheng = true;
			if(a[i] < 0) fu = true;
		}
		if(zheng && fu){
			bool flag = false;
			do{
				flag = false;
				for(int i = 2; i <= n - 1; i++){
					//1
					if(a[i] > 0 && dif(a[i + 1], a[i - 1])){
						if(a[i - 1] < 0 && abs(a[i - 1]) > a[i] + a[i + 1]){
							sove(i);flag = true;
						}
						else if(a[i - 1] > 0 && abs(a[i + 1]) > a[i] + a[i - 1]){
							sove(i);flag = true;
						}
					}
					//2
					if(a[i] < 0 && dif(a[i + 1], a[i - 1])){
						if(a[i - 1] > 0 && a[i - 1] > abs(a[i] + a[i + 1])){
							sove(i);flag = true;
						}
						if(a[i - 1] < 0 && a[i + 1] > abs(a[i] + a[i - 1])){
							sove(i);flag = true;
						}
					}
					//3
					if(Same(a[i - 1], a[i + 1]) && dif(a[i], a[i - 1]) && dif(a[i], a[i + 1])){
						if(a[i] < 0){
							if(a[i - 1] > abs(a[i] || a[i + 1] > abs(a[i]))){
								sove(i);flag = true;
							}
						}
						if(a[i] > 0){
							if(abs(a[i - 1]) > a[i] || abs(a[i + 1]) > a[i]){
								sove(i);flag = true;
							}
						}	
					}
				}
			
			}while(flag);	
		}
		int ans = -0x3f3f3f3f;
		
		for(int i = 1; i <= n; i++) ans = max(ans, abs(a[i]));
		printf("%d\n", ans);
	}
	return 0;
} 

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