Teza Round 1 (Codeforces Round 1015, Div. 1 + Div. 2)
A
观察样例有偶数一定不行,奇数的话我们就把1放在第一个,最大的放在第二个,其他顺次排列就ok了
#include<bits/stdc++.h> using namespace std; void slove() { int x; cin>>x; if(x%2==0) { cout<<-1<<endl; return; } vector<int> a(x+1); a[1]=x; for(int i=2;i<=x;i++) { a[i]=i-1; } for(int i=1;i<=x;i++) cout<<a[i]<<' '; cout<<endl; return; } int main() { int t; cin>>t; while(t--) slove(); return 0; }
B
想要找一个判断的充要和等价条件。经过观察有最小值一定得是d才行因为从必要性性的角度考虑如果min在最大gcd数组中那么它们的d一定小于等于min而另外的集合的任意数大于min显然不成立,那么我们就把能被min整除的数放在gcd集合中即可,然后再检查一下就ok了
#include<bits/stdc++.h> using namespace std; #define int long long int gcd(int a,int b) { if(b) return gcd(b,a%b); else return a; } void slove() { int n; cin>>n; vector<int> a(n); for(int i=0;i<n;i++) cin>>a[i]; sort(a.begin(),a.end()); vector<int> g; vector<int> s; int k=a[0]; s.push_back(k); for(int i=1;i<=n-1;i++) { if(a[i]%k==0) g.push_back(a[i]); else s.push_back(a[i]); } //cout<<g.size()<<endl; int t=g.size(); if(t==0) { cout<<"NO"<<endl; return; } int res=g[0]; for(int i=1;i<t;i++) { res=gcd(res,g[i]); } if(res==k) cout<<"YES"<<endl; else cout<<"NO"<<endl; return; } signed main() { int t; cin>>t; while(t--) slove(); }
C
观察到如果a[i]->b[i]的话b[i]->a[i]是一定的还得存一下a[i]的位置d,设置目标串为以a[i]->b[i]构造的回文串即可就是注意交换的时候要把所有的都存一下不然会保存错误
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; void slove() { int n; cin>>n; vector<int> a(n+1); vector<int> b(n+1); vector<int> h(n+1); vector<int> w(n+1); vector<int> d(n+1); int cnt=0; for(int i=1;i<=n;i++) { cin>>a[i]; d[a[i]]=i; } for(int i=1;i<=n;i++) { cin>>b[i]; if(a[i]==b[i]) cnt++; } for(int i=1;i<=n;i++) { h[a[i]]=b[i]; w[b[i]]=a[i]; } for(int i=1;i<=n;i++) { if(h[i]==w[i]) continue; else { cout<<-1<<endl; return; } } /*for(int i=1;i<=n;i++) cout<<a[i]<<' '; cout<<endl; for(int i=1;i<=n;i++) cout<<d[a[i]]<<' '; cout<<endl; cout<<endl;*/ vector<PII> q; if(n%2!=0) { if(cnt>1) { cout<<-1<<endl; return; } vector<int> c(n+1); int t=(n+1)/2; int x=0; for(int i=1;i<=n;i++) { if(a[i]==b[i]) { x=a[i]; break; } } c[t]=x; int l=1,r=n; vector<int> st(n+1,0); for(int i=1;i<=n;i++) { if(a[i]==x||st[a[i]]==1) continue; c[l]=a[i]; c[r]=h[a[i]]; st[a[i]]=1; st[h[a[i]]]=1; l++; r--; } //for(int i=1;i<=n;i++) cout<<c[i]<<' '; //cout<<endl; for(int i=1;i<=n;i++) { if(a[i]!=c[i]) { q.push_back({d[a[i]],d[c[i]]}); int u=a[i],v=c[i],x=d[a[i]],y=d[c[i]]; /*cout<<u<<' '<<v<<endl; cout<<x<<' '<<y<<endl;*/ a[i]=v; a[y]=u; d[u]=y; d[v]=x; /*for(int i=1;i<=n;i++) cout<<a[i]<<' '; cout<<endl; for(int i=1;i<=n;i++) cout<<c[i]<<' '; cout<<endl; for(int i=1;i<=n;i++) cout<<d[a[i]]<<' '; cout<<endl; cout<<endl;*/ } } /*for(int i=1;i<=n;i++) cout<<c[i]<<' '; cout<<endl;*/ } else { if(cnt!=0) { cout<<-1<<endl; return; } vector<int> c(n+1); int l=1,r=n; vector<int> st(n+1,0); for(int i=1;i<=n;i++) { if(st[a[i]]==1) continue; c[l]=a[i]; c[r]=h[a[i]]; st[a[i]]=1; st[h[a[i]]]=1; l++; r--; } for(int i=1;i<=n;i++) { if(a[i]!=c[i]) { q.push_back({d[a[i]],d[c[i]]}); int u=a[i],v=c[i],x=d[a[i]],y=d[c[i]]; /*cout<<u<<' '<<v<<endl; cout<<x<<' '<<y<<endl;*/ a[i]=v; a[y]=u; d[u]=y; d[v]=x; /*int u=d[a[i]]; d[a[i]]=d[c[i]]; d[c[i]]=u;*/ } } /*for(int i=1;i<=n;i++) cout<<c[i]<<' '; cout<<endl;*/ } cout<<q.size()<<endl; for(auto t : q) { cout<<t.first<<' '<<t.second<<endl; } return; } int main() { int t; cin>>t; while(t--) slove(); return 0; }
D
和数论整除余数有关,抽屉原理,找到最大的k1使得n/k1>=m+1,如果没有k1就等于k答案就是k和r的最大值因为我们可以在这m+1个0到k-1的串后面加上0到r-1(r为nmod(k1*m1)的余数)
#include<bits/stdc++.h> using namespace std; void slove() { int n,m,k,r; cin>>n>>m>>k; int m1=m+1; int k1=n/m1; if(k1<k) { r=n%(m*k); m1=m; k1=k; } else { r=n%(k1*m1); } vector<int> q; for(int i=1;i<=m1;i++) { for(int j=0;j<=k1-1;j++) { q.push_back(j); } } for(int i=0;i<=r-1;i++) q.push_back(i); for(int x : q) cout<<x<<' '; cout<<endl; } int main() { int t; cin>>t; while(t--) slove(); return 0; }