Codeforces Round 640 (Div. 4)

目录

A. Sum of Round Numbers

B. Same Parity Summands

C. K-th Not Divisible by n

D - Alice, Bob and Candies

E. Special Elements

F. Binary String Reconstruction

G. Special Permutation


A. Sum of Round Numbers


考察拆位

对每一个数直接把每一个位置的数拆下来即可,采用边计算边处理的方式更加好

void solve()
{
    cin>>n;
    while(n--){
        int x; cin>>x;
        int now=1;
        vector<int> ans;
        while(x){
            int y=x%10;
            if(y){
                ans.push_back(y*now);
            }
            x/=10;
            now*=10;
        }
        cout<<ans.size()<<endl;
        for(auto&v:ans) cout<<v<<' ';
        cout<<endl;
    }
    
    return ;
}


B. Same Parity Summands


考察奇偶处理

如果能拆成m个偶数一每一个偶数都>=2,奇数则是>=1所以只要前面都是2看最后一个是不是偶数,奇数同理

void solve()
{
    cin>>n>>m;
    if(n>=m*2 && (n-(m-1)*2)%2==0){
        cout<<"YES"<<endl;
        for(int i=1;i<=m-1;i++) cout<<2<<' ';
        cout<<n-(m-1)*2<<endl;
        return ;
    }
    if(n>=m && (n-(m-1))&1){
        cout<<"YES"<<endl;
        for(int i=1;i<=m-1;i++) cout<<1<<' ';
        cout<<n-(m-1)<<endl;
        return ;
    }
    cout<<"NO"<<endl;
    
    return ;
}



C. K-th Not Divisible by n


考察除法和模数

我们简单模拟可以发现每次倍数之能增加的都是n-1,则我们需要看有几个n-1在里面如果恰好是整数倍的话需要-1

void solve()
{
    cin>>n>>m;
    int x=m/(n-1),y=m%(n-1);
    if(!y){
        cout<<x*n-1<<endl;
    }
    else{
        cout<<x*n+y<<endl;
    }
    return ;
}


D - Alice, Bob and Candies


考察基础双指针

我们直接按照题目意思使用双指针模拟就好用,while写法会更加简洁
 

void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>w[i];
    
    int tim=0,a=0,b=0,lasta=0,lastb=0;
    int l=1,r=n;
    while(l<=r){
        tim++;
        while(l<=r && lasta<=lastb){
            a+=w[l];
            lasta+=w[l];
            l++;
        }
        if(l>r) break;
        lastb=0;
        tim++;
        while(l<=r && lastb<=lasta){
            b+=w[r];
            lastb+=w[r];
            r--;
        }
        lasta=0;
    }
    cout<<tim<<' '<<a<<' '<<b<<endl;
    
    return ;
}



E. Special Elements


前缀和和数据范围的处理注意到内存很小我们能不用map就不用,考虑范围很小使用n^2的前缀和来处理,注意每一次清空的只要是到n即可
 

bitset<N> ton;
int a[N],b[N];

void solve()
{
    cin>>n;
    
    for(int i=1;i<=n;i++){
         cin>>a[i];
         b[i]=b[i-1]+a[i];
    }
    for(int i=1;i<=n;i++) ton[i]=0;
    
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++){
            if(b[j]-b[i-1]<=n){
                ton[b[j]-b[i-1]]=true;
            }
        }
    
    int ans=0;
    for(int i=1;i<=n;i++)
        if(ton[a[i]]) ans++;
    
    cout<<ans<<endl;

    return ;
}


 

F. Binary String Reconstruction


简单构造

依照题目意思一定是有解的我们不妨先处理11和00,然后对10和01做分类讨论即可
模拟题细心研究细节

void solve()
{
    int a,b,c; cin>>a>>b>>c;
    if(c){// 构造 11
        for(int i=1;i<=c+1;i++) cout<<1;
    }
    if(a){// 构造00
        for(int i=1;i<=a+1;i++)  cout<<0;
    }
    
     if(b){// 表示10的数量1100
         if(c&&a){//    11100   我只要加一个就是1 就是加一接着加0 就是加一
             int cnt=1;
             while(cnt<b){
                  cout<<1;
                  cnt++;
                  if(cnt==b) break;
                  cout<<0;
                  cnt++;
             }
         }
         else if(c){
             int cnt=0;
             while(cnt<b){// 111
                  cout<<0;
                  cnt++;
                  if(cnt==b) break;
                  cout<<1;
                  cnt++;
             }
         }
         else if(a){// 00 
              int cnt=0;
              while(cnt<b){// 11100
                  cout<<1;
                  cnt++;
                  if(cnt==b) break;
                  cout<<0;
                  cnt++;
             }
         }
         else{
              int cnt=-1;
              while(cnt<b){// 11100
                  cout<<1;
                  cnt++;
                  if(cnt==b) break;
                  cout<<0;
                  cnt++;
             }
         }
     }
    cout<<endl;
    
    return ;
}



PS:简单写法

void solve()
{
       int a,b,c; cin>>a>>b>>c;
       string s; 
       for(int i=1;i<=a+1;i++) s+='0';// 一定会有一个0
       if(b==0&&c==0){
           cout<<s<<endl;
           return ;
       }
       
       int cnt=b;
       if(b==0) s.clear();
       
       c++;
       while(c--) s+='1';
       cnt--;
       
       if(cnt<=0){
           cout<<s<<endl;
           return ;
       }
       while(cnt){
           s+="0";
           cnt--;
           if(!cnt) break;
           s+='1';
           cnt--;
       } 
       cout<<s<<endl;
        return ;
}

G. Special Permutation

简单构造

首先手动模拟发现<=3不可以
我们直观的想法有直接按照由外向内的排列方式这样每个数都会隔开2,
但是对于中间位置我们却不好处理,会应为数变化但是我们钥匙从大到小
的从外到内来排序会发现中间的位置一定是2和1处于矛盾之中我们直接
交换2,4问题就迎刃而解

int a[N];

void solve()
{
    cin>>n;
    if(n<=3){
        cout<<-1<<endl;
        return ;
    }
    
    int l=1,r=n;
    int now=n;
    while(l<=r){
        a[l++]=now--;
        if(l>r) break;
        a[r--]=now--;
    }    
    for(int i=1;i<=n;i++){
        if(a[i]==2) cout<<4<<' ';
        else if(a[i]==4) cout<<2<<' ';
        else cout<<a[i]<<' ';
    }
    cout<<endl;
    return ;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值