Codeforces Round #696 (Div. 2) A-C

本文介绍了三道编程竞赛题目,涉及字符串处理、质数寻找和数组操作。第一题通过优化策略构造字符串b,使得结果最大化;第二题通过质数判断找到满足特定条件的因数组合;第三题通过迭代算法解决数组破坏问题,找到满足条件的数X。这些题目展示了编程竞赛中常见的思维技巧和算法应用。
摘要由CSDN通过智能技术生成

这场打得很烂
A. Puzzle From the Future
思路很简单
a、b都为0、1组成的字符串,然后将他们简单相加(1+1=2,0+1=1)
得到的那串字符串经过处理,重复的会被覆盖 02200会变成020
题目要使结果最可能最大,给出字符串a
求字符串b
思路:使当前位置尽可能大且不与前一位相同,建立一个now,表示前一位的数字,如果前一位是和是2 则这一位就和凑1,反之相反。比如如果前一位的和是1且a为0,则b当前位只能为0;

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		string s;
		cin>>s;
		cout<<1;
		int now=1+s[0]-'0';
		for(int i=1;i<s.length();i++){
			if(now!=s[i]-'0'+1){
				cout<<1;
				now=s[i]-'0'+1;
			}
			else{
				cout<<0;
				now=s[i]-'0';
			}
		}
		cout<<endl;
	}
}

B. Different Divisors
B题其实很简单,但是我数据范围看错了,以为是一个数学推论,但推不出来,后来才反应过来只要质数判断一下,暴力搜就过了,数据范围不大。
题意:找出一个数b至少有4个因数,且任意2个因数之间至少相差 a
思路:第一个因数就当做1 第四个因数当做 自身 ,就变成了找其中两个因数。但是因为其中的一个因数有因数,那一定也是b的因数,比如样例2,a=2 如果看做 1 3 6 12 时6的因数2也算是12的因数,所以不满足相差2.
所以结论是 这两个数一定是质数,才能满足,所以打一个质数表,去搜满足条件的最小的质数即可。

#include<bits/stdc++.h>
using namespace std;
 
int main(){
	vector<int> isprime(50000, 1); 
	for (int i = 2; i * i < 50000; i++) 
		for (int j = 2; j * i < 50000; j++) 
			isprime[j * i] = 0;
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		long long a,b;
		for(int i=1+n;;i++){
			if(isprime[i]){
				a=i;
				break;
			}
		}
		for(int i=a+n;;i++){
			if(isprime[i]){
				b=i;
				break;
			}
		}
		cout<<a*b<<endl;
	}
}

C. Array Destruction
当时也没想出来,后来补题的。
题意:找到一个数X为一个数组中两个数的和,然后X变为这两数中最大的那个数,继续在剩下的数组里找两个数和等于X,重复操作,直到数组为空。
思路:首先证明那两个数中大数一个一定是数组中最大的(如果这两个数都不是最大的,那么X会变成其中一个小数,那个最大的数将不会有数和它相加等于X)因为初始的X是未知的,但是一定是其中一个数与最大数相加的和,所以一个循环来举例一个数与最大数相加。再把所有数统计在map中,这样就可以知道(X-当前最大值)的那个数在不在数组里。

#include<bits/stdc++.h>
using namespace std;
vector<int>v;
int flag;
int a[10005];
map<int,int>vis;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		for(int i=1;i<=2*n;i++) cin>>a[i];
		sort(a+1,a+2*n+1);
		for(int i=1;i<=n*2;i++){
			v.clear();
			flag=1;
			int ix=n*2;
			int x=a[i]+a[n*2];
			vis.clear();
			for(int j=1;j<=n*2;j++) vis[a[j]]++;
			for(int j=1;j<=n;j++){
				while(!vis[a[ix]]) ix--; //用来更新ix的值
				vis[a[ix]]--;
				vis[x-a[ix]]--;
				v.push_back(x-a[ix]);
				v.push_back(a[ix]);
				if(vis[a[ix]]<0||vis[x-a[ix]]<0){
					flag=0;
					break;
				}
				x=a[ix];
				ix--;
			}
			if(flag) break;
		}
		if(flag){
			cout<<"YES"<<endl;
			cout<<v[0]+v[1]<<endl;
			for(int i=0;i<n;i++){
				cout<<v[i*2]<<" "<<v[i*2+1]<<endl;
			}
		}
		else cout<<"NO"<<endl;
	}
} 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠风丶北枝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值