1. 程式人生 > 實用技巧 >Codeforces Round #669 (Div. 2) A~C

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;
}