其他分享
首页 > 其他分享> > Codeforces Round #568 (Div. 2)

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\n",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\n",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\n",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

 

标签:568,cnt,int,scanf,d%,Codeforces,long,Div,define
来源: https://www.cnblogs.com/bxd123/p/11111359.html