Codeforces Round #696 (Div. 2),ABC三题

Codeforces Round #696 (Div. 2)题解

A. Puzzle From the Future

题目分析

要使得到的d最大
1:d的位数必然同样为n位,不能因为有连续的相同数导致位数减少
2:从最高位开始,每一位都尽可能的大,无需考虑后效性,因为越高位的数越大,d越大

代码实现:

循环控制每一位,从最高位开始,用k记录上一位d为多少,根据k的值和b的每一位值,决定a的该位值为多少,并重新更新k,例如:当k=1或者k=0时,若b[i]为1,则a[i]为1,k更新为2。

#include<iostream>
using namespace std;
 
char b[105000];
 
int main(){
    
    
	int T,n;
	cin>>T;
	while(T--){
    
    
		cin>>n;
		cin>>b;
	
		int k=0; 
		for(int i=0;i<n;i++){
    
    
			if(b[i]=='1'){
    
    
				if(k==0){
    
    
					cout<<1;
					k=2;
				}
				else if(k==1){
    
    
					cout<<1;
					k=2;
				}
				else if(k==2){
    
    
					cout<<0;
					k=1;
				}
			}
			else{
    
    
				if(k==1){
    
    
					cout<<0;
					k=0;
				}
				else if(k==2){
    
    
					cout<<1;
					k=1;
				}
				else if(k==0){
    
    
					cout<<1;
					k=1;
				}
			}
		}
		cout<<endl;
	}
	return 0;
} 

B. Different Divisors

题目分析

d至少已有两个因子:1和它本身
d还需要两个因子,
设这两个因子为x,y
且x<y
可以发现,x不能为合数,因为x的因子也为d的因子,这样就导致d有比x更小的因子t,若t满足条件2,则x直接修改为t即可,这样可以使得答案更小,所以x不能为合数。同理y也不能为合数。那么答案就是求得两个满足条件2的最小素数x,y,答案即为xy

代码实现

线性筛预处理出所有素数,lowerbound查找两个最小素数,相乘输出即可

#include<iostream>
#include<algorithm>
using namespace std;
 
long long prime[10000005],p[10000005],cnt,N=10000000;
 
void init(){
    
    
	p[0]=p[1]=1;
	for(int i=2;i<=N;i++){
    
    
		if(p[i]==0)prime[++cnt]=i;
		for(int j=1;j<=cnt;j++){
    
    
			if(prime[j]*i>N)break;
			p[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main() {
    
    
	int T,n;
	init();
	cin>>T;
	
	while(T--) {
    
    
		cin>>n;
		long long x=prime[lower_bound(prime+1,prime+cnt+1,1+n)-prime];
		long long y=prime[lower_bound(prime+1,prime+cnt+1,x+n)-prime];
		cout<<x*y<<endl;
	}
	return 0;
}

C. Array Destruction

扫描二维码关注公众号,回复: 13121329 查看本文章

题目分析

答案x必然为数组中最大数up与数组中其他数的和
第一步:枚举另一个数
第二步:每次都用up成为两个数的和,并将up更新为两个数的较大数,易知这两个数中的某一个数一定为比up小的次大数,不然该次大数与任何数的和,都比该轮两个数比较成的新的up值大,就无法在后续的操作中被用掉了

代码实现

第一步:循环枚举
第二步:用multiset存储除了枚举掉的那个数的其他数据,循环执行以下操作:从最大值开始寻找次大值,将他们的差的数值的计数器减1,并更新最大值为次大值,无法减时,该轮失败

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;

int a[5000],b1[5000],b2[5000],top;
multiset<int>s;

int main() {
    
    
	int T, n,ans;
	cin>>T;
	while (T--) {
    
    
		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<2*n;i++){
    
    
	    	top=0;
	    	b1[++top]=a[2*n];
	    	b2[top]=a[i];
	    	int up=a[2*n];
	    	
	    	s.clear();
	    	for(int j=1;j<2*n;j++){
    
    
	    		if(j!=i)s.insert(a[j]);
			}
			multiset<int>::iterator it1,it2;
			while(!s.empty()){
    
    
				it1=s.end();
				it1--;
				int temp=*it1;
				s.erase(it1);
				it2=s.find(up-temp);
				if(it2!=s.end()){
    
    
					s.erase(it2);
					b1[++top]=temp;
					b2[top]=up-temp;
					up=temp;
				}
				else{
    
    
					break;
				}
			}
			if(top==n){
    
    
				break;
			}
		}
        if(top==n){
    
    
        	cout<<"YES"<<endl;
        	cout<<b1[1]+b2[1]<<endl;
        	for(int i=1;i<=top;i++){
    
    
        		cout<<b2[i]<<" "<<b1[i]<<endl;
			}
		}
		else cout<<"NO"<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43602607/article/details/112879815