码迷,mamicode.com
首页 > 其他好文 > 详细

cf round#598 CDEF

时间:2019-11-05 22:09:31      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:efi   gif   break   pen   span   amp   转换   char   click   

C:模拟:未跳到目的地之前先贪心放板子,能到达目的地后紧贴着放板子

先判能不能跳到目的地,能跳到再考虑是否需要将后面的板子往前移动

技术图片
#include<bits/stdc++.h>
using namespace std;
#define N 20005
 
int sum,n,m,d,c[N],ans[N],ans1[N];
 
int main(){
    cin>>n>>m>>d;
    for(int i=1;i<=m;i++)cin>>c[i],sum+=c[i];
    
    if(sum>n){puts("NO");return 0;}
    
    int pos=0,id,R=0;
    for(id=1;id<=m;id++){
        if(pos+d>=n+1){//直接贴着放板子即可 
            for(int i=R+1;i<=R+c[id];i++)
                 ans[i]=id;
            R+=c[id];
        }
        else {//贪心放板子 
            pos+=d;//跳到pos+d去 
            for(int i=pos;i<=pos+c[id]-1;i++) 
                ans[i]=id;
            pos+=c[id]-1; 
            R=pos;
        }
    }
    
    if(pos+d<n+1){puts("NO");return 0;}
    if(pos+d>=n+1 && R<=n){
        puts("YES");
        for(int i=1;i<=n;i++)
            cout<<ans[i]<<" ";
        return 0;
    }
    
    int ind=n;
    for(int i=R;i>=1;i--){
        ind=min(ind,i);
        if(ans[i]){
            ans1[ind]=ans[i];
            ind--;
        }
    }
    puts("YES");
    for(int i=1;i<=n;i++)
        cout<<ans1[i]<<" ";
    return 0;
}
View Code

D:贪心往前移动0即可,注意k是long long

技术图片
#include<bits/stdc++.h>
using namespace std;
#define N 1000006
#define ll long long
long long n,k;
char s[N];
 
int main(){
    int q;cin>>q;
    while(q--){
        scanf("%lld%lld",&n,&k);
        scanf("%s",s+1);
        
        ll tot=0,len=0;
        for(int i=1;i<=n;i++){
            if(s[i]==1){
                tot++;
            }
            else {
                if(tot<=k){
                    k-=tot;
                    ++len;
                    swap(s[i],s[len]);
                }
                else {//只能往前移动k格 
                    swap(s[i],s[i-k]);
                    break; 
                }
            }
        }
        
        printf("%s\n",s+1);
    }
    
}
View Code

E:贪心,肯定是分队伍越多越好,六个人的队显然没有两只三人队优

先排序,dp[i]表示取前i人的最优解,

枚举3<=j<=5,dp[i]=min(dp[i-j]+a[i]-a[i-j+1]);

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define N 200005
 
struct Node{
    ll id,a;
}p[N];
ll n,ans[N],dp[N],pre[N];
int cmp(Node a,Node b){
    return a.a<b.a;
}
 
 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p[i].a;
        p[i].id=i;
    }
    sort(p+1,p+1+n,cmp);
    
    dp[3]=p[3].a-p[1].a;
    pre[3]=0;
    dp[4]=p[4].a-p[1].a;
    pre[4]=0;
    dp[5]=p[5].a-p[1].a;
    pre[5]=0;
    for(int i=6;i<=n;i++){
        dp[i]=dp[i-3]+p[i].a-p[i-2].a;
        pre[i]=i-3;
        for(int j=4;j<=5;j++){
            if(i-j<3)continue;
            if(dp[i]>dp[i-j]+p[i].a-p[i-j+1].a){
                dp[i]=dp[i-j]+p[i].a-p[i-j+1].a;
                pre[i]=i-j;
            }
        }        
    }
    
    cout<<dp[n]<< ;
    int pos=n,now=0;
    while(pos){
        ++now;
        int tmp=pre[pos];
        for(int i=tmp+1;i<=pos;i++)
            ans[p[i].id]=now;
        pos=tmp;
    }
    cout<<now<<\n;
    for(int i=1;i<=n;i++)cout<<ans[i]<< ;
}
View Code

F:将一长段逆转转换成每次只逆转相邻两个字符,如果字符集不同,显然不行

字符集相同:分成两种情况:

  1,某种字符出现>=2次,那么这种情况必然有解:先将这两个字符挨在一起,然后就可以随便搞了

  2,每种字符出现1次,那么求出s转换成t的步数,偶数有解,奇数无解

技术图片
#include<bits/stdc++.h>
using namespace std;
#define N 200005
 
char s[N],t[N];
int n,cnt1[100],cnt2[100],pos1[100],pos2[100];
 
int main(){
    int T;cin>>T;
    while(T--){
        for(int i=0;i<26;i++)
            cnt1[i]=cnt2[i]=pos1[i]=pos2[i]=0;
        
        cin>>n;
        cin>>s>>t;
        for(int i=0;i<n;i++)
            cnt1[s[i]-a]++,cnt2[t[i]-a]++;
        
        int flag=0;
        for(int i=0;i<26;i++)
            if(cnt1[i]!=cnt2[i])
                flag=1;
        if(flag){puts("NO");continue;}
        
        flag=0;
        for(int i=0;i<26;i++)
            if(cnt1[i]>=2)
                flag=1;
        if(flag){puts("YES");continue;}
        
        int sum=0;
        for(int i=0;i<n;i++){
            int pos=i;
            while(s[pos]!=t[i])pos++;
            for(int j=pos;j>i;j--){
                swap(s[j],s[j-1]);
                sum++;
            }    
        }
        
        if(sum%2==0)cout<<"YES\n";
        else puts("NO");
    }
} 
View Code

 

cf round#598 CDEF

标签:efi   gif   break   pen   span   amp   转换   char   click   

原文地址:https://www.cnblogs.com/zsben991126/p/11801393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!