Codeforces Round #135 (Div. 2)

来源:互联网 发布:莫斯科奥运会知乎 编辑:程序博客网 时间:2024/06/05 07:47

Codeforces Round #135 (Div. 2)  http://codeforces.com/contest/219


cf 再次悲剧了……11:30 开始,寝室早就断电了,只能靠笔记本电池艰难地维持那么一个多小时,而且没有灯,也不能再草稿纸上演算真心累呀……结果这次cf只A了前两个题目结尾,而且其中有个题目还不是1A,可怜……

 

A k-String
  水题,随便yy下就行了,当每个字符出现的次数都是k的倍数的时候存在满足条件的字符串
#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long ll;char s[1010];int cnt[100];int main(){     int k;     while(cin>>k>>s)     {         int len=strlen(s);         for(int i=0;i<len;i++)           cnt[s[i]-'a']++;         bool ok=1;         for(int i=0;i<26&&ok;i++)            if(cnt[i]%k!=0) ok=0;         if(ok)         {             string s="";            for(int i=0;i<26;i++)               if(cnt[i])               {                   for(int j=0;j<cnt[i]/k;j++)                     s+=(char)('a'+i);               }             while(k--)              cout<<s;             cout<<endl;         }         else puts("-1");     }     return 0;}

B
Special Offer! Super Price 999 Bourles
 这个题目还是比较有意思的题目,要多想会儿。 
题意: 给出 p 和  d ,要求 [ p-d , p] 这个区间范围内找包含末尾包含9的个数最多的数,如果多个数满足条件那么就找最大的那
思路:  我是枚举要找的末尾9的个数,然后再贪心找离p最近的数(这样的数只有一个),取最后值即可
个。
#include <iostream>#include <cstdio>using namespace std;typedef long long ll;int main(){     ll a,b;     while(cin>>a>>b)     {         ll cnt=0,ans=0,d=a;         while(d) cnt++,d/=10;         for(ll i=1,x=10;i<=cnt;i++,x*=10)         {             if(x-1>a) break;             ll rest=a%x,dd=a/x;             ll tmp;             if(rest==x-1) tmp=dd*x+x-1;             else tmp=(dd-1)*x+x-1;             if(tmp<a-b) break;             ans=tmp;         }         if(ans) cout<<ans<<endl;         else cout<<a<<endl;     }     return 0;}

C
Color Stripe
这个题题意都不讲了,比赛的时候就是卡在这个题目上了,贪心dp都可以
dp做法:dp[ len [k ] 表示 把第len个数涂成k眼色前len块满足条件的最优解,即最少图的次数
#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;#define maxn 500010#define inf 0x3fffffffchar s[maxn];int n,k,dp[maxn][26];void dfs(int id,int d,int pre){    if(id<0) return;    for(int i=0;i<k;i++)      if(dp[id][i]==d&&i!=pre)      {          dfs(id-1,d- (i!=s[id]),i);          putchar(i+'A');          break;      }}int main(){    while(scanf("%d%d",&n,&k)==2)    {        scanf("%s",s);        for(int i=0;i<n;i++) s[i]-='A';        for(int i=1;i<n;i++)        for(int j=0;j<k;j++) dp[i][j]=inf;        for(int j=0;j<k;j++) dp[0][j]= (j!=s[0]);        for(int i=1;i<n;i++)        for(int j=0;j<k;j++)        for(int r=0;r<k;r++)           if(j!=r) dp[i][j]=min(dp[i][j],dp[i-1][r]+(s[i]!=j));        int Min=dp[n-1][0];        for(int i=1;i<k;i++) Min=min(Min,dp[n-1][i]);        printf("%d\n",Min);       /* for(int i=0;i<n;i++)        {            for(int j=0;j<k;j++)              cout<<dp[i][j]<<" ";            cout<<endl;        }*/        dfs(n-1,Min,-1);        puts("");    }    return 0;}

贪心做法 , 不过我确实不怎么会证明为什么这样做就会ac,是我自己瞎yy出来的,贪心做法要快很多

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long ll;const int inf=0x3fffffff;char s[500010];int dp[500010][30];int len,k;void change(char &cc,char a,char b){   for(int i=0;i<k;i++)      if(i+'A'!=a&&i+'A'!=b) { cc=i+'A';break; }}int main(){    while(scanf("%d%d",&len,&k)==2)    {        scanf("%s",s);        int t=0;        if(k==2)        {            int t1=0,t2=0;            for(int i=0;i<len;i++)               if(s[i]!=i%2+'A') t1++;            for(int i=0;i<len;i++)               if(s[i]!=(i+1)%2+'A') t2++;            if(t1>t2){                printf("%d\n",t2);                for(int i=0;i<len;i++) putchar((i+1)%2+'A');                puts("");            }else{                printf("%d\n",t1);                for(int i=0;i<len;i++) putchar(i%2+'A');                puts("");            }            continue;        }        for(int i=0;i<len;i++)          if(i+1<len&&s[i]==s[i+1])            t++,change(s[i+1],s[i],s[i+2]);        printf("%d\n%s\n",t,s);    }    return 0;}

E
Parking Lot
如果做个跟这个类似的题目的话,直接就是水题了,两次dfs 即可,还有没有太坑爹没有爆栈
#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn=500010;int dp[maxn];vector<pair<int,bool> > g[maxn];vector<int> ans;int Min1(int &a,int b){    if(a>b)    {        a=b;return 1;    }    return 0;}void dfs(int u,int fa){    int sz=g[u].size();    for(int i=0;i<sz;i++)    {        int v=g[u][i].first;        bool ok=g[u][i].second;        if(v==fa) continue;        dfs(v,u);        dp[u]+=dp[v]+ok;    }}void dfs1(int u,int fa){    int sz=g[u].size();    for(int i=0;i<sz;i++)    {        int v=g[u][i].first;        bool ok=g[u][i].second;        if(v==fa) continue;        dp[v]=dp[u]+ (ok?-1:1);        dfs1(v,u);    }}int main(){    int n,a,b;    while(scanf("%d",&n)==1)    {        for(int i=1;i<n;i++)        {            scanf("%d%d",&a,&b);            g[a].push_back(make_pair(b,0));            g[b].push_back(make_pair(a,1));        }        memset(dp,0,sizeof(dp));        dfs(1,-1);        dfs1(1,-1);        int Min=dp[1];        for(int i=1;i<=n;i++)          Min1(Min,dp[i]),g[i].clear();        for(int i=1;i<=n;i++)          if(Min==dp[i]) ans.push_back(i);        printf("%d\n%d",Min,ans[0]);        for(int i=1;i<ans.size();i++)          printf(" %d",ans[i]);        puts("");        ans.clear();    }    return 0;}

E
Parking Lot
 线段树的区间和并,蛋疼,调试了我好长时间,不知道wa了多少次,太弱了

#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 200010int lsum[maxn<<2],msum[maxn<<2],rsum[maxn<<2],ans[1000001];void pushup(int rt,int l){    lsum[rt]=lsum[rt<<1];    if(lsum[rt<<1]==l-l/2) lsum[rt]+=lsum[rt<<1|1];    rsum[rt]=rsum[rt<<1|1];    if(rsum[rt<<1|1]==l/2) rsum[rt]+=rsum[rt<<1];    msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);}void build(int l,int r,int rt){    lsum[rt]=msum[rt]=rsum[rt]=r-l+1;    if(l==r) return;    int m=(l+r)>>1;    build(lson);    build(rson);}void update(int p,int val,int l,int r,int rt){    if(l==r)    {        lsum[rt]=msum[rt]=rsum[rt]=val;        return;    }    int m=(l+r)>>1;    if(p<=m) update(p,val,lson);    else update(p,val,rson);    pushup(rt,r-l+1);}int query(int p,int l,int r,int rt){    if(l==r) return l;    int m=(l+r)>>1;    if(msum[rt<<1]>=p) return query(p,lson);    else if(rsum[rt<<1]+lsum[rt<<1|1]>=p) return query(p-rsum[rt<<1],rson);    else return query(p,rson);}int main(){    int n,m,id,a;    while(scanf("%d%d",&n,&m)==2)    {        build(1,n,1);       // update(6,0,1,n,1);        while(m--)        {            scanf("%d%d",&id,&a);            if(id==1)            {                int Max=max(lsum[1],max((msum[1]+1)/2,rsum[1])),np;                if(Max==lsum[1]) np=1;                else if((msum[1]+1)/2==Max)                {                    if(msum[1]%2==0)                       np=query(msum[1]-1,1,n,1)-msum[1]/2+1;                    else np=query(msum[1],1,n,1)-msum[1]/2;                }else np=n;                update(np,0,1,n,1);                printf("%d\n",np);                ans[a]=np;            }            else update(ans[a],1,1,n,1);        }    }    return 0;}



原创粉丝点击