Codeforces Round #426 (Div. 2)

本文解析了三道编程挑战题目,包括字符旋转方向判断、门守卫分配问题及游戏得分可能性验证。通过具体实现思路和代码示例,帮助读者理解解决这些问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A

题意:给出两个字符,在所给次数情况下,问第一个字符旋转到第二个字符是顺时针方向还是逆时针方向或者都可以

思路:直接判断即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define ft first
#define sd second
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 1e5 + 10;
const int MOD = 1e9 + 7;
char st[qq];
char match[] = {'^', '>', 'v', '<'};

int main(){
	gets(st);
	int t;	scanf("%d", &t);
	int a, b;
	for(int i = 0; i < 4; ++i) {
		if(st[0] == match[i])	a = i;
	}
	for(int i = 0; i < 4; ++i) {
		if(st[2] == match[i])	b = i;
	}
	int cw, ccw;
	if(b > a) {
		cw = b - a;
	} else {
		cw = 4 - (a - b);
	}
	if(a > b) {
		ccw = a - b;
	} else {
		ccw = 4 - (b - a);
	}
	if(cw == t && t == ccw) {
		puts("undefined");
	} else if(cw == t) {
		puts("cw");
	} else if(ccw == t) {
		puts("ccw");
	} else {
		if((t - cw) % 4 == 0 && (t - ccw) % 4 == 0) {
			puts("undefined");
		} else if((t - cw) % 4 == 0) {
			puts("cw");
		} else {
			puts("ccw");
		}
	}
	
	return 0;
}

B

题意:这座城市有26个门,分别由字母A到Z代表,现在有n个人和k个守卫,首先门都是关闭的,如果某个人要去一个还没有开门的门的话就需要一个守卫取给他开门,指导最后一个走这个门的人走过去了,守卫才可以离开,现在知道n个人需要去那个门的顺序,问是否存在有人进不去门的情况

思路:记录一下每一扇门最后一个人走的位置,然后每次判断这个门是否已经开了,没开人就需要放守卫,知道走着这个门的最后一个人走守卫才可以离开,也就是说就是判断k值是否小于0即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define ft first
#define sd second
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 1e6 + 10;
const int MOD = 1e9 + 7;
char st[qq];
bool vis[qq];
int r[30];
bool ishas[30];

int main(){
	int n, k;	scanf("%d%d", &n, &k);
	scanf("%s", st);
	mst(r, -1);
	for(int i = 0; i < n; ++i) {
		r[st[i] - 'A'] = max(r[st[i] - 'A'], i);
	}
	for(int i = 0; i < 30; ++i) {
		if(r[i] == -1)	continue;
		vis[r[i]] = true;
	}
	int f = 0;
	for(int i = 0; i < n; ++i) {
		if(!ishas[st[i] - 'A'])	{
			ishas[st[i] - 'A'] = true;
			if(k) k--;
			else {
				f = 1;
				break;
			}
		}
		if(vis[i])	k++;
	}
	if(f == 0)	puts("NO");
	else	puts("YES");
	return 0;
}

C

题意:给出n,代表一共进行n局游戏,每局游戏又有m个回合,游戏是这样进行的,首先两人分数起始都是1,每回合选一个自然数k,赢得人分数 × k^2, 输得人分数 × k,没回和的k可以不一样,m也是任意的,问你是否存在存在最后两人分数是a b的情况

思路:

假设进行m回合,每回合选择的是ki,则我们知道每回和 ki^2 * ki = ki^3

则我们知道a * b = (k1 * k2 * ... * km)^ 3

假设 x = k1 * k2 * ... km

即a * b = x^3, 然后问题就转化为判断a * b的结果是不是某个数的立方了

但是有个问题比如数据1 * 27 = 3^3 但这并不能构造出来

实际上 a = x * (yi * yj ...) (i, j代表a这个人赢的回合的编号)

同理b也一样,所以我们还需要判断 (a / x) * (b / x) == x ?

#include <cstdio>
#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define ft first
#define sd second
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 1e6 + 10;
const int MOD = 1e9 + 7;
const LL MAXN = 1e18;
LL num[qq];
LL Find(LL l, LL r, LL x) {
	while(l <= r) {
		LL mid = (l + r) / 2;
		if(num[mid] == x)	return mid;
		else if(num[mid] < x) {
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return -1;
}

int main(){
	LL cnt;
	for(cnt = 1; cnt * cnt * cnt <= MAXN; ++cnt) {
		num[cnt] = cnt * cnt * cnt;
	}
	int t;	scanf("%d", &t);
	while(t--) {
		LL a, b;	scanf("%lld%lld", &a, &b);
		LL ans = Find(1, cnt - 1, a * b);
		if((a / ans) * (b / ans) == ans) {
			puts("Yes");
		} else {
			puts("No");
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值