2021csp 赛前第二次集训 - 模拟专题

仔细探究,以下代码有哪些错误?
#include <bits/stdc++.h>
using namespace std;

int n, a[10000][10000];
long long ans;

int main() {
	scanf("%d", n);
	ans = 1 << n;
	printf("%lld", ans);

	ans = 1 << 63;
	printf("%lld", ans);
	
	int b[1000000];

	return 0;
}
2013 提高组D1T1 转圈游戏
  • 循环 k 次,计算10^k % n; 因为 k 的范围很大,超时
#include <bits/stdc++.h>
using namespace std;

long long n, m, k, x, ans;

int main() {
	cin >> n >> m >> k >> x;
	
	ans = m;
	for (int i = 1; i <= k; i ++) {
		ans = ans * 10 % n;
	}

	ans = (x + ans) % n;
	cout << ans << endl;
		
	return 0;
}

/*
0	->	m
1	->	1+m
2	->	2+m
...
n-m	->	(n-m)+m=0
...
n-1	->	(n-1)+m	->	m-1

观察规律,
x号小伙伴 1轮后走到 (x + m) % n 号位置 
x号小伙伴 2轮后走到 (x + m*2) % n号位置 
...... 
x号小伙伴 t轮后走到 (x + m*t) % n号位置 

ans =	(x + m * 10^k) % n
 	=	(x + m * (10^k % n)) % n
*/
  • 因为 k很大,所以用快速幂求出10^k % n的结果
#include <bits/stdc++.h>
using namespace std;

long long n, m, k, x, ans, base = 10;

int main() {
	cin >> n >> m >> k >> x;
	
	ans = m;
	while (k) {
		if (k & 1) ans = ans * base % n;
		base = base * base % n;
		k /= 2;
	}

	ans = (x + ans) % n;
	cout << ans << endl;
		
	return 0;
}
2014 提高组D1T1 生活大爆炸版石头剪刀布
  • 模运算的运用
  • 二维数组的理解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 210;
int n, na, nb;
int a[N], b[N];
int e[5][5] = {	0,-1,1,1,0, 
				1,0,-1,1,-1, 
				-1,1,0,-1,1, 
				-1,-1,1,0,1, 
				1,1,-1,-1,0
				};

int main() {
	cin >> n >> na >> nb;
	for (int i = 0; i < na; i ++) cin >> a[i];
	for (int i = 0; i < nb; i ++) cin >> b[i];

	int score_a = 0, score_b = 0;
	for (int i = 0; i < n; i ++) {
		int x = a[i%na];
		int y = b[i%nb];
		if (e[x][y] == 1) score_a ++;
		if (e[y][x] == 1) score_b ++;
	}
	cout << score_a << ' ' << score_b << endl;
		
	return 0;
}
2016 提高组D1T1 玩具谜题
  • 循环排列,模运算的使用
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int n, m;
int face[N];	
string job[N];

int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i ++) {
		cin >> face[i] >> job[i];			//朝向,职业 
	}
	
	int x = 0;								//第一个小人是 0号 
	while (m --) {
		int a, s;							
		cin >> a >> s;
		//如果第 x个小人朝内(face[x]==0),向左数(a==0) -> 顺时针
		//如果第 x个小人朝外(face[x]==1),向右数(a==1) -> 顺时针
		//总结:如果face[x] == a,顺时针;否则,逆时针 
		if (face[x] != a) x = (x + s) % n;	//逆时针
		else x = (x + n - s) % n;			//顺时针 
	}
	cout << job[x] << endl;

	return 0;
}
2008 提高组T2 火柴棒等式
#include <bits/stdc++.h>
using namespace std;

int a[10] = {6,2,5,5,4,5,6,3,7,6};
int n, cnt, t, ans;

int main() {
	cin >> n;
	
	//加数和被加数最大只能是 1111 
	for (int i = 0; i <= 1111; i ++) {
		for (int j = 0; j <= 1111; j ++) {
			cnt = 0;
			
			t = i; 			//加数 
			do { cnt += a[t%10]; t /= 10; } while (t);
			
			t = j;			//被加数 
			do { cnt += a[t%10]; t /= 10; } while (t);
			
			t = i + j;		//和 
			do { cnt += a[t%10]; t /= 10; } while (t);

			//去掉 + 和 =,数字用掉 n - 4根火柴棒 
			if (cnt == n - 4) ans ++;
		}
	}
	cout << ans;

	return 0;
}
2015 提高组D1T1 神奇的幻方
#include <bits/stdc++.h>
using namespace std;

const int N = 50;
int n, a[N][N];

int main() {
	cin >> n;
	int x = 1, y = n + 1 >> 1;
	for (int i = 1; i <= n*n; i ++) {
		a[x][y] = i;
		
		if (x == 1 && y != n) x = n, y ++;			//条件 1 
		else if (x != 1 && y == n) x --, y = 1;		//条件 2
		else if (x == 1 && y == n) x ++;			//条件 3
		else if (a[x-1][y+1]) x ++;					//条件 4
		else x --, y ++;							//其它 
	}
	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			cout << a[i][j] << ' ';
		}
		cout << endl;
	}

	return 0;
}
2014 D2T1 无线网络发射器选址
#include <bits/stdc++.h>
using namespace std;

const int N = 2e7 + 10;
int d, n, a[130][130];	//a[i][j]表示设置在(i,j)处的发射器可以覆盖的公共场所数量 
int x, y, k;
int h[N];				//注意:长度为 2e7的int类型的数组,大小为80MB 

int main() {
	scanf("%d%d", &d, &n);
	
	while (n --) {
		scanf("%d%d%d", &x, &y, &k);
		//每个路口 (x,y),可以被距离为 d以内的发射器所覆盖 
		for (int i = max(0, x-d); i <= min(128, x+d); i ++) {
			for (int j = max(0, y-d); j <= min(128, y+d); j ++){
				//坐标为(i,j)处的发射器能够覆盖的公共场所数量增加 k 
				a[i][j] += k;	
			}
		}
	}
	
	for (int i = 0; i <= 128; i ++) {
		for (int j = 0; j <= 128; j ++) {
			h[a[i][j]] ++;
		}
	}

	int ans;
	for (int i = 20000000; i >= 1; i --) {
		if (h[i]) {
			ans = i;
			break;
		}
	}
	printf("%d %d\n", h[ans], ans);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值