codeforces 357

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\n",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\n",ans); else puts("-1"); return 0; }

 

posted @ 2016-12-09 21:12  _LinesYao  阅读(159)  评论(0编辑  收藏  举报