Codeforces Round #669 (Div. 2) A~C
阿新 • • 發佈:2020-09-09
分三種情況,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; }