Codeforces Round #402 (Div. 2)

本文提供了四道算法竞赛题目的详细解答过程,涉及数字分配、数位DP、贪心策略及字符串匹配等内容,通过代码实现展示了高效解决问题的方法。

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

A

很顯然兩種相同的數字要平分到兩個組裏面去, 即這個數字的總數要是偶數

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

using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 1e5 + 10;
int n, m;
int a[10], b[10];

int main(){
	scanf("%d", &n);
	int x;
	for(int i = 0; i < n; ++i){
		scanf("%d", &x);
		a[x]++;
	}
	for(int i = 0; i < n; ++i){
		scanf("%d", &x);
		b[x]++;
	}
	bool flag = true;
	int sum = 0;
	for(int i = 1; i <= 5; ++i){
		if((a[i] + b[i]) % 2 == 1){
			flag = false;
			break;
		}
		sum += abs(a[i] - b[i]) / 2;
	}
	if(!flag)	puts("-1");
	else if(sum % 2 == 1)	puts("-1");
	else	printf("%d\n", sum / 2);
	return 0;
}

B

這題的話剛開始確實不知道怎麼去做

後來看看n的大小,  hhh不知道怎麼想到n的長度了, 直接二進制枚舉剩下的數字, 然後判斷就行了

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

using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 1e5 + 10;
int n, m, k;
char st[105];
int num[qq];

int main(){
	scanf("%s%d", st, &k);
	ll mod = 1;
	for(int i = 1; i <= k; ++i)
		mod *= 10ll;
	int n = strlen(st);
	int minx = 15;
	for(int i = 0; i < (1 << n); ++i){
		ll sum = 0;
		int cnt = 0;
		for(int j = 0; j < n; ++j)
			if(i & (1 << j))	sum = sum * 10 + st[j] - '0', cnt++;
		if(sum % mod == 0){
			int digit = 0;
			if(sum == 0)	digit = 1;
			else{
				while(sum){
					sum /= 10;
					digit++;
				}
			}
			int p = cnt - digit;
			minx = min(minx, n - cnt + p);
		}
	}
	printf("%d\n", minx);
	return 0;
}

稍微注意一下全部選出的是0的情況



C

這題也挺簡單的, 就是說n個物品現在價格是ai, 一周後價格是bi, 你要買下這n個物品, 但是現在就必須買至少k個, 很顯然如果一個物品一周之後價格邊高了, 那麼肯定現在就要把它買下來,  也就是按b[i] - a[i] 排一個序, 先選k個, 如果後面的物品還是漲價就繼續買, 一直買到它沒有或者買到的物品降價爲止

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

using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m, k;
struct Item{
	int a, b;
	bool operator < (const Item &it)const{
		return b - a > it.b - it.a;
	}
}item[qq];

int main(){
	scanf("%d%d", &n, &k);
	int cnt = 0;
	for(int i = 0; i < n; ++i)
		scanf("%d", &item[i].a);
	for(int i = 0; i < n; ++i){
		scanf("%d", &item[i].b);
		if(item[i].b < item[i].a)	cnt++;
	}
	sort(item, item + n);
	ll sum = 0;
	for(int i = 0; i < k; ++i)
		sum += item[i].a;
	int p;
	for(p = k; p < n; ++p)
		if(item[p].b - item[p].a >= 0)	sum += item[p].a;
		else	break;
	for( ; p < n; ++p)
		sum += item[p].b;
	printf("%lld\n", sum);
	return 0;
}

D

題意:給兩個串a, b, 然後給出a串的刪除順序...  問最多刪除多少個字符之後b串仍然是a串的字串

在剛看這題的時候沒有想法, 因爲注意力在串上, 後來看了看序列, 知道好像可以二分, 隨後就寫嘛, 我是二分檢查mid的可行性, 在看樣例2的時候發現 哦... 好像不具備單調性...

和別人討論了一下說沒有單調性的題意肯定理解錯了,  我又回去讀題意, 好像真的讀錯了, 題目保證了

Sergey wants to stop her as late as possible.

It is guaranteed that the word p can be obtained by removing the letters from word t.

這裏其實說明了只要刪除後的a串只要子序列中還存在b串, 那麼就還可以繼續刪(我KMP的做法是把它當字串去做了....)

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

using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m;
string a, b;
int num[qq];
bool id[qq];
/*void getnext(){
	int i = 0, j = -1;
	int len = (int)b.size();
	next[0] = -1;
	while(i < len){
		if(j == -1 || b[i] == b[j])
			next[++i] = ++j;
		else	j = next[j];
	}
}
bool KMP(string c){
	int i = 0, j = 0;
	int lenc = (int)c.size(), lenb = (int)b.size();
	while(i < lenc && j < lenb){
		if(j == -1 || c[i] == b[j])
			++i, ++j;
		else	j = next[j];
	}
	if(j == lenb)	return true;
	return false;
}
bool check(int k){
	if((int)a.size() - k > (int)b.size())	return false;
	string c;
	for(int i = 0; i < k; ++i)
		id[i] = num[i];
	sort(id, id + k);
	int p = 0;
	for(int i = 0; i < (int)a.size(); ++i){
		if(i + 1 == id[p])	p++;
		else	c += a[i];
	}

	if(KMP(c)) return true;
	return false;
}*/
int main(){
	cin >> a >> b;
	n = (int)a.size();
	for(int i = 0; i < n; ++i)
		scanf("%d", num + i);
	m = (int)b.size();
	int l = 0, r = n;
	int ans = 0;
	while(l <= r){
		int mid = (l + r) / 2;
		memset(id, false, sizeof(id));
		for(int i = 0; i < mid; ++i)
			id[num[i] - 1] = true;
		int pos = 0;
		for(int i = 0; i < n; ++i){
			if(id[i])	continue;
			if(a[i] == b[pos])	pos++;
			if(pos >= m)	break;
		}
		if(pos >= m){
			ans = mid;
			l = mid + 1;
		}else{
			r = mid - 1;
		}
	}
	printf("%d\n", ans);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值