Codeforces Round #624 (Div. 3)
题目链接:https://codeforces.com/contest/1311
A. Add Odd or Subtract Even
小于差奇和大于差偶一次操作即可,其余两次,复杂度为$O_{(1)}$。
#include <bits/stdc++.h> using namespace std; void solve() { int a,b;cin>>a>>b; int ans=0; if(a<b) if((a-b)&1) ans=1; else ans=2; else if(a>b) if((a-b)&1) ans=2; else ans=1; cout<<ans<<"\n"; } int main() { int t;cin>>t; while(t--) solve(); return 0; }
B. WeirdSort
双指针局部排序,复杂度为$O_{(nlogn)}$。
#include <bits/stdc++.h> using namespace std; void solve() { int n,m;cin>>n>>m; int a[n];for(int &i:a) cin>>i; int p[m];for(int &i:p) cin>>i,--i; sort(p,p+m); for(int i=0;i<m;i++){ int l=p[i],r=p[i]+2; while(i<m&&p[i+1]==p[i]+1) ++r,++i; sort(a+l,a+r); } cout<<(is_sorted(a,a+n)?"YES":"NO")<<"\n"; } int main() { int t;cin>>t; while(t--) solve(); return 0; }
C. Perform the Combo
有些类似于差分,正逆序累加都可以,复杂度为$O_{(n)}$。
#include <bits/stdc++.h> using namespace std; void solve() { int n,m;cin>>n>>m; string s;cin>>s; int cnt[n]={1}; for(int i=0;i<m;i++){ int t;cin>>t; ++cnt[0],--cnt[t]; } int ans[26]={}; for(int i=0;i<n;i++){ if(i)cnt[i]+=cnt[i-1]; ans[s[i]-'a']+=cnt[i]; } for(int i=0;i<26;i++) cout<<ans[i]<<" \n"[i==25]; } int main() { int t;cin>>t; while(t--) solve(); return 0; }
#include <bits/stdc++.h> using namespace std; void solve() { int n,m;cin>>n>>m; string s;cin>>s; int cnt[n]={}; cnt[n-1]=1; for(int i=0;i<m;i++){ int t;cin>>t; ++cnt[t-1]; } int ans[26]={}; for(int i=n-1;i>=0;i--){ if(i<n-1) cnt[i]+=cnt[i+1]; ans[s[i]-'a']+=cnt[i]; } for(int i=0;i<26;i++) cout<<ans[i]<<" \n"[i==25]; } int main() { int t;cin>>t; while(t--) solve(); return 0; }
D. Three Integers
枚举,复杂度为$O_{(n\sqrt{n})}$。
#include <bits/stdc++.h> using namespace std; const int M=11000; void solve() { int a,b,c;cin>>a>>b>>c; int mi=INT_MAX; int ans_a,ans_b,ans_c; for(int i=1;i<=M;i++) for(int j=i;j<=M;j+=i) for(int k=j;k<=M;k+=j){ int cost=abs(a-i)+abs(b-j)+abs(c-k); if(cost<mi){ mi=cost; ans_a=i,ans_b=j,ans_c=k; } } cout<<mi<<"\n"; cout<<ans_a<<' '<<ans_b<<' '<<ans_c<<"\n"; } int main() { int t;cin>>t; while(t--) solve(); return 0; }
E. Construct the Binary Tree
先构成深度和最大的链,然后双指针增删,复杂度为$O_{(n)}$。
#include <bits/stdc++.h> using namespace std; void solve() { int n,d;cin>>n>>d; vector<int> v(n+1,1); int l=1,r=n-1,p=n*(n-1)/2-d; while(l<r){ while(p<r-l||v[l]==v[l-1]*2&&l<r) ++l; if(l<r){ ++v[l]; p-=r-l; --r; } } if(p!=0) cout<<"NO\n"; else{ cout<<"YES\n"; int pre=1; for(int i=1;i<=l;i++){ for(int j=0;j<v[i];j++) cout<<pre+j/2<<' '; pre+=v[i-1]; } cout<<"\n"; } } int main() { int t;cin>>t; while(t--) solve(); return 0; }
F. Moving Points
这题好像是树状数组或线段树,学过再填。

浙公网安备 33010602011771号