Codeforces Round #669 (Div. 2) A~C

分三种情况,0多直接输出0
1多直接输出满足要求的偶数个1
一样多的时候,如果是0是偶数直接输出k/2个0
否则用第一个0替换一个奇数位置的1即可

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL mod= 1e9+7;
const unsigned int N = 1e5+10;
int cnt[1010];
int cnt1[1010];
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
	#endif
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int _n;
	cin>>_n;
	while(_n--){
		int n;
		cin>>n;
		vector<int> a(n);
		int sum = 0;
		for(int i=0; i<n; i++){
			cin>>a[i];
			sum += a[i];
		}
		if(sum<=n/2){
			cout<<n/2<<endl;
			for(int i=0; i<n/2; i++)
				cout<<0<<" ";
			cout<<endl;
		}else{
			cout<<sum<<endl;
			if(sum%2==0){
				rep(i, 0, sum)
					cout<<1<<" ";
				cout<<endl;
			}else{
				vector<int> ans(sum, 1);
				for(int i=0; i<n; i++){
					if(a[i]==0){
						if(i&1||i==sum){
							ans[i-1]=0;
						}else{
							ans[i]=0;
						}
						break;
					}
				}
				for(int i=0; i<sum; i++)
					cout<<ans[i]<<" ";
				cout<<endl;
			}
		}
	}
	return 0;
}

最开始还以为是唯一分解,后来想了下怎么都要n方复杂度,那么直接暴力就可以了

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL mod= 1e9+7;
const unsigned int N = 1e5+10;
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
	#endif
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int _n;
	cin>>_n;
	while(_n--){
		int n;
		cin>>n;
		vector<int> a(n);
		rep(i,0,n) cin>>a[i];
		sort(a.begin(),a.end(), std::greater<int>());
		int gcd = a[0];
		int ma;
		int temp = 0;
		int index = 0;
		for(int i=0; i<n; i++){
			ma=__gcd(gcd,a[i]);
			for(int j=i; j<n; j++){
				temp=__gcd(gcd, a[j]);
				if(temp>=ma){
					index = j;
					ma = temp;
				}
			}
			std::swap(a[index], a[i]);
			gcd = ma;
		}
		rep(i,0,n) cout<<a[i]<<" ";
		cout<<endl;
	}
	return 0;
}

事实就是如果 amodb>bmoda 那么b比a大,而且a=amodb
于是可以发下,对于每两个未知的数
请求两次那么可以确定一个数,这样可以知道
求n个数最多只需要2n次请求,而且因为最后一个数不需要询问
所以总的次数是2
n-2次,满足要求

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL mod= 1e9+7;
const unsigned int N = 1e5+10;


int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
	#endif
	int n;
	cin>>n;
	vector<int> ans(n);
	vector<int> temp;
	for(int i=0; i<n; i++){
		temp.push_back(i+1);
	}
	int input[2];
	vector<int> gg;
	while(temp.size()>1){
		gg.resize(0);
		for(int i=0; i<(int)temp.size()-1; i+=2){
			cout<<"? "<<temp[i]<<" "<<temp[i+1]<<endl;
			cout.flush();
			cin>>input[0];
			cout<<"? "<<temp[i+1]<<" "<<temp[i]<<endl;
			cout.flush();
			cin>>input[1];
			if(input[0]<input[1]){
				ans[temp[i+1]-1]=input[1];
				gg.push_back(temp[i]);
			}
			else{
				ans[temp[i]-1]=input[0];
				gg.push_back(temp[i+1]);
			}
		}
		if(temp.size()&1)
			gg.push_back(temp.back());
		temp = gg;

	}
	ans[temp.back()-1]=n;
	cout<<"! ";
	for(int i=0; i<n; i++)
		cout<<ans[i]<<" ";
	cout<<endl;
	cout.flush();
	return 0;
}
posted @ 2020-09-09 13:26  CrosseaLL  阅读(90)  评论(0编辑  收藏  举报