Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)

本文解析了四道经典的编程题目,包括验证数列是否单调、字符替换、寻找初始分数的可能性及最小时间路径问题。每道题目均提供了清晰的思路说明与完整的代码实现。

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

A

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
int num[qq];

int main(){
	int n;	scanf("%d", &n);
	REP(i, 1, n){
		scanf("%d", num + i);
	}
	int c = 1;
	while(c < n && num[c] < num[c + 1])	c++;
	while(c < n && num[c] == num[c + 1])	c++;
	while(c < n && num[c] > num[c + 1])	c++;
	if(c >= n)	puts("YES");
	else	puts("NO");
	return 0;
}



B

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

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 100;
map<char, char> mp;
char a[qq], b[qq];
char st[1005];

int main(){
	scanf("%s%s", a, b);
	int len = strlen(a);
	for(int i = 0; i < len; ++i)
		mp[a[i]] = b[i];
	scanf("%s", st);
	for(int i = 0; i < strlen(st); ++i){
		if(st[i] >= '0' && st[i] <= '9')	printf("%c", st[i]);
		else{
			if(st[i] >= 'A' && st[i] <= 'Z')	printf("%c", mp[st[i] - 'A' + 'a'] - 'a' + 'A');
			else	printf("%c", mp[st[i]]);
		}
	}
	puts("");
	return 0;
}





C

题意:有k个评委按顺序给出k个分数,参赛者之前有一个分数,然后k个评委的分一个接一个的加上去,现在只知道n(n <= k)个中间分数(不包含初始分数并且这n个分数是无序的),问初始分数有多少种可能。

思路:n个分数中,我们只要确定某个分数的位置那么其初始分数就确定了,那么我们枚举某个分数在k中的位置,然后判断可行性即可

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2000 + 10;
int a[qq], b[qq];
int sum[qq];

int main(){
	int n, k;	scanf("%d%d", &n, &k);
	REP(i, 0, n - 1){
		scanf("%d", a + i);
	}
	sum[0] = a[0];
	REP(i, 1, n - 1){
		sum[i] = sum[i - 1] + a[i];
	}
	sort(sum, sum + n);
	n = unique(sum, sum + n) - sum;
	REP(i, 0, k - 1){
		scanf("%d", b + i);
	}
	int ans = n;
	REP(i, 0, n - 1){
		int x = b[0] - sum[i];
		REP(j, 1, k - 1){
			if(!binary_search(sum, sum + n, b[j] - x)) {
				ans--;
				break;
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}


D

题意:n个人k把钥匙以及一个终点p,都位于一条直线上,现在每个人要走到终点并且要拿到一把钥匙,问最短时间

思路:二分答案 + 贪心,对于每一个确定的答案,那么我们即可知道每个人能走动的l,r区间,对区间进行左端点排序,然后最左边的拿最左边的钥匙贪心

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<LL, LL>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2000 + 10;
LL pl[qq], kl[qq];
LL n, k, p;
pill node[qq];
bool Check(LL x){
	for(int i = 0; i < n; ++i){
		if(x < abs(p - pl[i]))	return false;
		LL dis = (x - abs(p - pl[i])) / 2;
		LL l = p, r = pl[i];
		if(l > r)	swap(l, r);
		l -= dis;
		r += dis;
		node[i] = mk(l, r);
	}
	sort(node, node + n);
	int cur = 0;
	for(int i = 0; i < n; ++i){
		while(cur < k && kl[cur] < node[i].first)	cur++;
		if(cur < k && kl[cur] <= node[i].second)	cur++;
		else	return false;	
	}
	return true;
}


int main(){
	scanf("%lld%lld%lld", &n, &k, &p);
	for(int i = 0; i < n; ++i){
		scanf("%lld", pl + i);
	}
	sort(pl, pl + n);
	for(int i = 0; i < k; ++i){
		scanf("%lld", kl + i);
	}
	sort(kl, kl + k);
	LL l = 0, r = 1e18, mid;
	LL ans;
	while(l <= r){
		mid = (l + r) / 2;
		if(Check(mid)){
			ans = mid;
			r = mid - 1;
		}else{
			l = mid + 1;
		}
	}
	printf("%lld\n", ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值