C 题意:
###n个勇士编号1-n,m个回合对战,每个回合由仍留在游戏里的编号Li~Ri的人参加,胜者为Xi,输的人退出游戏。
###求一个a1-an的序列,若ai为胜者,则ai=0,否则ai=打败ai的勇士的编号。
思路:
解法一:使用set,输的人擦除。
#include<bits/stdc++.h> using namespace std; set<int> s; set<int>::iterator it,lp; int ans[500005]={0},del[300005]; int main() { int n,m,l,r,win; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) s.insert(i); while(m--) { scanf("%d%d%d",&l,&r,&win); lp=s.lower_bound(l); int cnt=0; for(it=lp;*it<=r&&it!=s.end();++it) { if(*it==win) continue; ans[*it]=win; del[cnt++]=*it; } for(int i=0;i<cnt;++i) { s.erase(del[i]); } } for(int i=1;i<=n;++i) { printf("%d ",ans[i]==i?0:ans[i]); } return 0; }
D 题意:http://codeforces.com/problemset/problem/357/D
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1000005; char a[maxn],b[maxn]; ll cnt[maxn][30]={0}; ll gcd(ll x, ll y) { return y==0?x:gcd(y,x%y); } int main() { ll n,m,g,alen,blen,len,ans=0; scanf("%I64d%I64d",&n,&m); scanf("%s%s",a,b); alen=strlen(a); blen=strlen(b); g=gcd(alen,blen); len=alen*blen/g; for(int i=0;i<alen;++i) ++cnt[i%g][a[i]-'a']; for(int i=0;i<blen;++i) ans+=cnt[i%g][b[i]-'a']; ans=n*alen-n*alen/len*ans; printf("%I64d ",ans); return 0; }
E 题意:有n个车厢,每个车厢有4个人,其中ai个学生,交换最少的人使得每个车厢的学生数为0或3或4,无法达成输出-1。
思路:贪心。统计车厢内学生为1,2,3,4的数目cnt[1],cnt[2],cnt[3],cnt[4]。
目标为最少的步数,过程中应先配出cnt[3],配不出3时考虑4。
首先考虑cnt[1]不为0时,尽可能让cnt[1]与cnt[2]配对,这样可以同时减少cnt[1]与cnt[2]的数目使二者符合要求,明显最优,即1 2 -> 3。
然后考虑让三个1抱团 1 1 1 -> 3 ;剩下一个1时考虑 1 3 -> 4;剩下两个1时先考虑1 1 3 3 -> 4 4 ,再考虑1 1 -> 2。
这些过程后若cnt[1]!=0,则无解。
考虑cnt[2]不为0时,2 2 2 -> 3 3;剩下一个2时先考虑 2 4 -> 3 3,再考虑 2 3 3 -> 4 4;剩下两个2时考虑 2 2 -> 4。
#include<bits/stdc++.h> using namespace std; int cnt[10]={0}; int main() { int n,x,ans=0,t; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%d",&x); ++cnt[x]; } if(!cnt[1]&&!cnt[2]) { puts("0"); return 0; } if(cnt[1]) { if(cnt[2]) { // 1 2 -> 3 t=min(cnt[1],cnt[2]); ans+=t; cnt[1]-=t; cnt[2]-=t; cnt[3]+=t; } if(cnt[1]) {
// 1 1 1 -> 3 ans+=cnt[1]/3*2; cnt[3]+=cnt[1]/3; cnt[1]%=3;
if(cnt[1]==2) { if(cnt[3]>=2) ans+=2,cnt[3]-=2,cnt[4]+=2; // 1 1 3 3 -> 4 4 else ++ans,++cnt[2]; // 1 1 -> 2 } else if(cnt[1]==1) { if(cnt[3]) ++ans,--cnt[3],++cnt[4]; // 1 3 -> 4 else if(cnt[1]&&cnt[4]<2) { puts("-1"); return 0; } else cnt[4]-=2,ans+=2,cnt[3]+=3; // 1 4 4 -> 3 3 3 } cnt[1]=0; } } if(cnt[2]) {
// 2 2 2 -> 3 3 ans+=cnt[2]/3*2; cnt[3]+=cnt[2]/3*2; cnt[2]%=3;
if(cnt[2]==2) ans+=2,cnt[2]=0,++cnt[4]; // 2 2 -> 4 else if(cnt[2]==1) { if(cnt[4]) ++ans,cnt[2]=0,--cnt[4],cnt[3]+=2; // 2 4 -> 3 3 else if(cnt[3]>=2) ans+=2,cnt[2]=0,cnt[3]-=2,cnt[4]+=2; // 2 3 3 -> 4 4 else { puts("-1"); return 0; } } } if(!cnt[1]&&!cnt[2]) printf("%d ",ans); else puts("-1"); return 0; }