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次请求,而且因为最后一个数不需要询问
所以总的次数是2n-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;
}
一条有梦想的咸鱼