codeforces Round #669 (Div. 2) 1407A Ahahahahahahahaha

题目链接

在这里插入图片描述

题目翻译:

给你一个偶数长度,由0和1组成的数组a。数组元素的编号从1到n枚举。你最多能够去除n/2个数字使得数组的交替和等于0(a1-a2+a3-a4+…=0)。也就是说编号为奇数的数字和等于编号为偶数的数字和。你可以去除任意位置的数字。
比如,如果你有一个数组a = [1,0,1,0,0,0],你可以去除编号为2和4的数字,这样a会变成[1,1,0,0],其交替和为1-1+0-0=0。

解题思路:

因为数组只由0和1两种数字组成,这表示0和1中至少有一种数字的数量大于等于n/2。而题目要求最多能够去除n/2个数字,所以我们可以去除数量少的那种数字,使得剩下的数字全是0或者全是1,并且其剩余数量一定大于等于n/2。其中如果剩下的全是1,且数量为奇数个,我们就需要去除一个1。这时候可能会疑惑去除一个1会不会使得剩下的数不足n/2个,答案是不会。有两种情况,一种是0和1的个数相等,且都是奇数,这种情况我们可以直接输出奇数个0;另一种情况是0和1的个数都是奇数,但1的个数-0的个数大于等于2(因为n是偶数,0和1的个数都是奇数,所以在0和1的个数不相等的情况下,差会大于等于2),所以去除一个1之后,1的数量仍然大于等于n/2。
总结:统计0和1的个数,如果0的个数大于等于1的个数,输出所有0;如果1的个数大于0的个数,输出所有1,其中如果1是奇数,少输出一个1。

代码:
#include<iostream>
using namespace std;
int t,n;
const int N = 1010;
int main() {
    
    
//	freopen("1.txt","r",stdin);
	cin>>t;
	while(t--) {
    
    
		int a[N],s1=0,s2=0;
		cin>>n;
		for(int i=0; i<n; i++) {
    
    
			cin>>a[i];
			if(a[i]==0) s1++;
			else s2++;
		}
		if(s1>=s2) {
    
    
			cout<<s1<<endl;
			for(int i=0; i<s1; i++) cout<<0<<" ";
			cout<<endl;
		} else {
    
    
			if(s2%2!=0) {
    
    
				s2--;
			}
			cout<<s2<<endl;
			for(int i=0; i<s2; i++) cout<<1<<" ";
			cout<<endl;
		}
	}
	return 0;
}
总结:

这种题花了我二十多分钟才想出来,凡是这种分数不高的签到题,就该往简单了想。特别注意细节,比如题目要求“最多能够去除n/2个数字”,不要看错了看成“去除尽可能少的数”。

猜你喜欢

转载自blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/108507812
今日推荐