CF996

A

link

如果两只小动物只往中间跳的话,那么中间间隔奇数个就是另一个小动物赢(一定会出现两个小动物挨着而该爱丽丝跳了),否则就是爱丽丝赢(一定会出现两个小动物挨着而改另一个动物跳了)。
那么我们可以发现,两个小动物只会往中间跳,因为往边上跳跳出去再跳回来一定是偶数步,不会改变自己的输赢(即不改变奇偶性)。

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int n,a,b;

void qwq(){
	
	cin >> n >> a >> b;
	if(a%2 == b%2) cout << "YES\n";
	else cout << "NO\n";
	
}

signed main(){
	
	int _;
	cin >> _;
	while(_--) qwq();
	
	return 0;
	
}

B

link

如果我们选了i又选了j,一定不优,因为(不妨设i<j)原数组会变成
a12,a22ai12,ai,ai+12aj12,aj,aj+12an12,an2(不难得出,手推一下即可)。
所以我们一定只改变一个,那么我们首先看看我们需要改变几个,如果是一个,再看看其它数多出的能否满足它的需求。

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int n;
int a[200005];
int gs,wz;
int b[200005];

void qwq(){
	
	cin >> n;
	gs = 0;
	for(int i = 1;i <= n;++ i)
		cin >> a[i];
	for(int i = 1;i <= n;++ i){
		cin >> b[i];
		if(b[i] > a[i]) gs++,wz = i;
	}
	
	if(gs >= 2) cout << "NO\n";
	else if(gs == 0) cout << "YES\n";
	else{
		for(int i = 1;i <= n;++ i){
			if(i != wz&&a[i]-b[wz]+a[wz] < b[i]){
				cout << "NO\n";
				return;
			}
		}
		cout << "YES\n";
	}
	
}

signed main(){
	
	int t;
	cin >> t;
	while(t--) qwq();
	
	return 0;
	
}

C

link

我们设每一行每一列的和为x,那么有xn=xm,当n!=m的时候,x只有等于0才能满足条件。
那么我们就让每一行每一列的和为0去求空着的。
怎么求呢?(设当前在位置x,y)我们知道,如果下一步要往右边走,那么一定不会再走到左边(即第1 y列),那么第1 y列的数除了这个都已经确定了,那么我们可以根据每一列的和为0求出该点;下一步往下走同理。

点击查看代码
#include<bits/stdc++.h>

#define int long long

using namespace std;

int n,m;
char s[2005];
int a[1005][1005];
int sum[2][1005];

void qwq(){
	
	cin >> n >> m;
	cin >> s+1;
	for(int i = 1;i <= n;++ i){
		for(int j = 1;j <= m;++ j){
			cin >> a[i][j];
			sum[0][i] += a[i][j];
			sum[1][j] += a[i][j];
		}
	}
	
	int x = 1,y = 1;
	for(int i = 1;i <= n+m-2;++ i){
		if(s[i] == 'R'){
			a[x][y] = 0-sum[1][y];
			sum[0][x] += a[x][y];
			sum[1][y] += a[x][y];
			y++;
		}
		else{
			a[x][y] = 0-sum[0][x];
			sum[0][x] += a[x][y];
			sum[1][y] += a[x][y];
			x++;
		}
	}
	a[n][m] = 0-sum[0][n];
	sum[0][n] += a[n][m];
	sum[1][m] += a[n][m];
	
	for(int i = 1;i <= n;++ i){
		for(int j = 1;j <= m;++ j)
			cout << a[i][j] << " ";
		cout << endl;
	}
	
}

signed main(){
	
	int _;
	cin >> _;
	while(_--) qwq();
	
	return 0;
	
}

D

link

真不如去看这个。。。
一个大模拟,看注释吧。。。
在注释中可能有一些话难以理解,我会在那句话后面画一个括号对应到上面来。
(1)大家可能对这里的加/减tim不太理解,这里我们过去了tim秒,但是我们前面并没有管后面的稻草人,其实他们在这些时间里也是移动的。
(2)推着:因为乌鸦要和稻草人保持k的距离,所以我们可以认为一个离乌鸦正好为k的稻草人,它往前一步,乌鸦也往前一步,所以我们可以认为稻草人是在推着乌鸦走。而前面的稻草人是不可能距离乌鸦小于k的,由于我们的算法,他也不会大于k

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int n,k,l;
int a[200005];

void qwq(){
	
	cin >> n >> k >> l;
	k *= 2;l *= 2;
	for(int i = 1;i <= n;++ i)
		cin >> a[i],a[i] *= 2;
	//为了避免分数,让所有涉及到时间的都乘2
	
	int x = 0;
	//乌鸦位置
	int at = 1;
	//乌鸦前面离他最近的稻草人的编号
	int tim = 0;
	//时间
	while(at+1 <= n&&a[at+1] == 0) at++;
	//去除前面都在零的那些稻草人
	if(a[1] > 0){
		tim += a[1];
		a[1] = 0;
		//首先让最前面的稻草人到0的位置和乌鸦重合
		//(这里不理解先看后面
	}
	
	while(1){
		x = a[at]+k;
		//重合了,乌鸦传到了当前位置+k
		//(因为重合了,当前位置就是a[at]
		if(x >= l) break;
		//如果已经到达l了,退出
		//每次的目的:
		//让乌鸦后面里乌鸦最近的稻草人和乌鸦重合
		if(at+1 <= n){
			//如果乌鸦后面还有稻草人
			//(1)
			if(a[at+1]-tim > x){
				//如果在前面的时间里一直往前走
				//也无法和x重合
				//那么我们就再用一些时间让他们两个重合
				tim += (a[at+1]-tim-x)/2;
				//为什么除以2呢?
				//因为在乌鸦前面的稻草人可以推着他
				//往后走,去找稻草人(2)
				at++;
				a[at] -= tim;
				//一直往前走(走了时间这么多,减去时间
			}
			else if(a[at+1]+tim >= x){
				//乌鸦在这个稻草人往前走的范围内
				//也在往后走的范围内
				//说明稻草人可以走到乌鸦的位置
				//那就让稻草人在乌鸦的位置
				at++;
				a[at] = x;
			}
			else{
				//否则,让稻草人往后走到
				//当前时间内能走到的位置
				at++;
				a[at] += tim;
			}
		}
		else{
			//乌鸦后面没有稻草人了
			tim += l-x;
			//前面那个稻草人推着乌鸦往前走l-x个位置(2)
			//从x(当前位置)走到l
			break;
		}
	}
	
	cout << tim << endl;
	
}

signed main(){
	
	int t;
	cin >> t;
	while(t--) qwq();
	
	return 0;
	
}
posted @   不认命,就是哪吒的命!  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示