• Codeforces Round #568 (Div. 2)


    B. Email from Polycarp

    题意:给定一个原串 一个输出串   因为键盘问题  按键按一下可能出现多个   判断原创和输出串是否匹配

    如  hello  和 heellooooooo  是匹配的

     

    指针扫一遍即可  优先级  原串大于last 

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e6+6;
    char s1[N],s2[N];
    int main()
    {
        int cas;RI(cas);
        while(cas--)
        {
            RS(s1);RS(s2);
            if(strlen(s1)>strlen(s2)){puts("NO");continue;}
            int last=-1;
            int lena=strlen(s1);
            int lenb=strlen(s2);
            int L=0;
            int ok=0;
            rep(i,0,lenb-1)
            {
                if(s2[i]==s1[L]&&L<lena)
                {
                    L++;last=s2[i];continue;
                }
                else if( s2[i]==last )
                {
                    continue;
                }
                else {L=0;break;}
            }
            if(L==lena)puts("YES");
            else puts("NO");
        }
        return 0;
    }
    View Code

    C2. Exam in BerSU (hard version)

    有n个物品 背包限重为m

    第i个物品重量为ai   输出n个数   求前i个物品 中  最少拿出多少个物品  使得能够装入背包(第i个答案一定包含第i个物品)

    贪心即可:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=2e5+5;
    
    int cnt[N],a[N];
    int num;
    int main()
    {
        ll n,m,x;
        cin>>n>>m;
        rep(i,1,n)
        {
            RI(a[i]);int t=m-a[i],s=0;
            rep(j,1,100)
            {
                if(t>j*cnt[j])t-=j*cnt[j],s+=cnt[j];
                else {s+=t/j;break;}
            }
            printf("%d
    ",i-1-s);
            ++cnt[a[i]];
        }
        return 0;
    }
    View Code

    D. Extra Element

    题意:给出n个数 要求能否去掉一个  使之成为一个等差数列

    比赛的时候少考虑了一种方法wa到爆炸  

    首先将其排序  前三个数字分别为 abc

    公差一共有三种可能   b-a    c-b   c-a   然后模拟即可求解 (比赛的时候少考虑了  c-a)

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=2e6+5;
    struct node
    {
        int pos;
        ll v;
    }a[N],b[N],c[N];
    bool cmp(node a,node b)
    {
        return a.v<b.v;
    }
    int main()
    {
        int n;RI(n);
     
        if(n<=3){printf("1");return 0;}
     
        rep(i,1,n)scanf("%lld",&b[i].v),b[i].pos=i,a[i]=c[i]=b[i];
        sort(a+1,a+1+n,cmp);
        sort(b+1,b+1+n,cmp);
        sort(c+1,c+1+n,cmp);
     
        ll d=a[2].v-a[1].v;
        int cnt=0;
        int ok=1;
        int flag=a[1].pos;
     
        rep(i,2,n)
        {
            if(a[i].v-a[i-1].v==d)continue;
            else
            {
                cnt++;
                a[i].v=a[i-1].v;
                flag=a[i].pos;
                if(cnt>1)
                {
                    ok=0;break;
                }
            }
        }
        if(ok)
        {
            printf("%d",flag);return 0;
        }
     
         d=b[3].v-b[2].v;
         cnt=1;
         ok=1;
         flag=b[1].pos;
     
        rep(i,3,n)
        {
            if(b[i].v-b[i-1].v==d)continue;
            else
            {
                ok=0;break;
            }
        }
        if(ok)
        {
            printf("%d",flag);return 0;
        }
     
        d=c[3].v-c[1].v;
        ok=1;
        flag=c[2].pos;
        rep(i,4,n)
        {
            if(c[i].v-c[i-1].v==d)continue;
            else
            {
                ok=0;break;
            }
        }
        if(ok)
        {
            printf("%d",flag);return 0;
        }
     
        printf("-1");
     
        return 0;
    }
    丑陋の代码

    超高效题解:

    #include<bits/stdc++.h>
    using namespace std;
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    #define F2(i,a,b) for(int i=a;i<(b);++i)
    #define dF(i,a,b) for(int i=a;i>=(b);--i)
    #define MN 200005
    #define ll long long
    #define mod 998244353
    int n;
    int a[MN],b[MN],c[MN];
    map<int,int>mp;
    int cc;
    void ad(int x){if(mp[x]==0)++cc;++mp[x];}
    void su(int x){--mp[x];if(mp[x]==0)--cc;}
    void ans(int v){F(i,1,n)if(b[i]==v){printf("%d
    ",i);break;}}
    int main(){
        scanf("%d",&n);
        if(n<=3)return puts("1"),0;
        F(i,1,n)scanf("%d",a+i),b[i]=a[i];
        sort(a+1,a+n+1);
        F(i,1,n-1)c[i]=a[i+1]-a[i];
        F(i,1,n-1)ad(c[i]);
        F(i,1,n){
            if(i==1){
                su(c[1]);
                if(cc==1)return ans(a[1]),0;
                ad(c[1]);
            }
            else if(i==n){
                su(c[n-1]);
                if(cc==1)return ans(a[n]),0;
                ad(c[n-1]);
            }
            else{
                su(c[i-1]),su(c[i]),ad(c[i-1]+c[i]);
                if(cc==1)return ans(a[i]),0;
                su(c[i-1]+c[i]),ad(c[i]),ad(c[i-1]);
            }
        }
        puts("-1");
        return 0;
    }
    View Code

    E. Polycarp and Snakes

    题意:给出一个n行m列的 . 阵表示什么都没有   上面可以加小写字母

    判断是否是   输出所有字母条  要求满足条件:

    小写字母可以被大写字母覆盖   (也就是说先画更小的)

    同种字母只能是一条直线  且必须连续(除了被覆盖的情况)

    字母必须升序(这点很好解决  直接完全覆盖即可  )

    强行暴力即可  比较考验码力qaq

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e4;
    char mp[N][N];
    int n,m,ans[N][4],cnt,vis[N];
    map<int,pair<int,int> >pos;
    map<int,int>flag;
    int ok=1;
     
    void judge(int id,int x,int y,int flag)
    {
        int x1=x,x2=x,y1=y,y2=y;
        ++cnt;
     
        if(flag==0)
        {
            ans[cnt][0]=ans[cnt][2]=x;
            ans[cnt][1]=ans[cnt][3]=y;
        }
        else if(flag==1)
        {
            rep(i,y,m)if(mp[x][i]==id)x2=x,y2=i;
            repp(i,y,1)if(mp[x][i]==id)x1=x,y1=i;
            ans[cnt][0]=x1;ans[cnt][1]=y1,ans[cnt][2]=x2,ans[cnt][3]=y2;
            rep(i,y1,y2)
            if(mp[x][i]<id||mp[x][i]=='.')ok=0;
        }
        else if(flag==2)
        {
            rep(i,x,n)if(mp[i][y]==id) x2=i,y2=y;
            repp(i,x,1)if(mp[i][y]==id)x1=i,y1=y;
            ans[cnt][0]=x1;ans[cnt][1]=y1,ans[cnt][2]=x2,ans[cnt][3]=y2;
            rep(i,x1,x2)
            if(mp[i][y]<id||mp[i][y]=='.')ok=0;
        }
        vis[cnt]=id;
    }
     
     
    int main()
    {
        int cas;RI(cas);
        while(cas--)
        {
            cnt=0;
            vis[0]='a'-1;
            pos.clear();flag.clear();
            RII(n,m);
            rep(i,1,n)RS(mp[i]+1);
     
            ok=1;
            rep(i,1,n)rep(j,1,m)
            {
                if(islower(mp[i][j]))
                {
                    if(!pos.count(mp[i][j]))
                    pos[mp[i][j]]=make_pair(i,j);
                    else
                    {
                        if(pos[mp[i][j]].first!=i&&pos[mp[i][j]].second!=j)ok=0;
                        if(pos[mp[i][j]].first==i)
                        {
     
                            if(flag[mp[i][j]]==2){ok=0;break;}
                            else flag[mp[i][j]]=1;
                        }
                        else if(pos[mp[i][j]].second==j)
                        {
                            if(flag[mp[i][j]]==1){ok=0;break;}
                            else flag[mp[i][j]]=2;
                        }
                    }
                }
            }
            if(!ok){puts("NO");continue;}
     
            rep(i,'a','z')
            if(pos.count(i))
            {
                judge(i,pos[i].first,pos[i].second,flag[i]);
                if(!ok)break;
            }
     
            if(!ok){puts("NO");}
            else
            {
                puts("YES");
                cout<<vis[cnt]-'a'+1<<endl;
     
                rep(i,1,cnt)
                {
                    int temp=vis[i]-vis[i-1];
                    while(temp--)
                    printf("%d %d %d %d
    ",ans[i][0],ans[i][1],ans[i][2],ans[i][3]);
                }
            }
        }
        return 0;
    }
    View Code

    F. Two Pizzas

    题意:有n个人  每个人喜欢 某几种配料    有m个披萨  每个披萨 有一个价格 且 包含几种配料  (配料数小于9)

    他们要订2个披萨  如果某个人的配料需求 全部被满足  说明这个人被满足  

    如何订披萨满足最多人的情况下 价格最小

    一开始枚举披萨再枚举人  一共三重循环  直接超时了

    考虑到 状态小  可以直接枚举状态  

    一开始维护每种相同披萨状态的最小价格

    那么如果答案是买两个相同(配料披萨)  就wa了

    所以要维护次小值

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=2e5+10;
     
    int n,m,x,a,ans1=1,ans2=2,maxx=0,temp,price,peo[N],minn1[N],minn2[N],id[N],id2[N];
     
    ll money=1e14;
    int main()
    {
        RII(n,m);
        rep(i,1,n)
        {
            int s=0;RI(x);
            while(x--)
            {
                RI(a);s|=1<<(a-1);
            }
            peo[s]++;
        }
        rep(i,0,1<<9)minn1[i]=minn2[i]=inf;
        rep(i,1,m)
        {
            int s=0,c;RII(c,x);
            while(x--)
            {
                RI(a);s|=1<<(a-1);
            }
            if(c<minn1[s]){minn1[s]=c;id[s]=i;}
            else if(c<minn2[s]){minn2[s]=c;id2[s]=i;}
        }
        int tot=1<<9;
        rep(i,0,tot)
        rep(j,i+1,tot)
        if(minn1[i]<inf&&minn1[j]<inf)
        {
     
            int cnt=0;
            rep(k,0,tot)if( ((i|j)&k)==k )cnt+=peo[k];
            if(cnt>maxx){maxx=cnt;ans1=id[i],ans2=id[j];money=minn1[i]+minn1[j];  }
            else if(cnt==maxx&&minn1[i]+minn1[j]<money){ans1=id[i],ans2=id[j];money=minn1[i]+minn1[j];}
        }
     
        rep(i,0,tot)
        if(minn1[i]<inf)
        {
            int cnt=0;
            rep(k,0,tot)if( ((i)&k)==k )cnt+=peo[k];
            if(cnt==maxx&&minn1[i]+minn2[i]<money){ans1=id[i],ans2=id2[i];money=minn1[i]+minn2[i];}
        }
     
        cout<<ans1<<" "<<ans2;
        return 0;
    }
    View Code

    G1. Playlist for Polycarp (easy version)

    题意:一个人有n首歌   时间为m

    每首个有两个元素  时间和 种类  (一共三种)

    要求求出 安排列表的数量  使得每个安排列表  总的时间恰好为m  且不会有两种相同种类的歌连续听

    状压do[state][last] 表示 当前听的个的状态 和最后一首听的歌曲的种类

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e5;
    ll dp[1<<16][4];
    const int mod=1e9+7;
    ll ans;
    int n,m;
    int t[N],v[N];
    int main()
    {
        RII(n,m);
        rep(i,1,n)RII(t[i],v[i]),dp[1<<(i-1)][ v[i] ]=1
     
        rep(state,0,(1<<n)-1 )
        rep(last,1,3)
        rep(now,1,n)
        {
            if(state&1<<(now-1))continue;
            if(last==v[now])continue;
            int k=state|(1<<now-1);
            dp[k][ v[now] ]=(dp[k][v[now]]+dp[state][last])%mod;
        }
        rep(state,1,(1<<n)-1)
        {
            int sum=0;
            rep(j,1,n)
            {
                if(state&(1<<(j-1)))
                sum+=t[j];
            }
            if(sum==m)
            {
                rep(k,1,3)
                ans=(ans+dp[state][k])%mod;
            }
        }
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    linux cmake安装方法
    Linux下安装numpy
    linux下安装opencv3.0
    linux升级gcc
    php session获取不到的解决方法
    python Tesseract安装方法
    SQLite-编译指示
    第十章:定积分
    7. 错误、调试和测试
    钱纳里的工业化阶段理论
  • 原文地址:https://www.cnblogs.com/bxd123/p/11111359.html
Copyright © 2020-2023  润新知