Codeforces Round #652 (Div. 2) A-D题

比赛链接:https://codeforces.com/contest/1369
A.FashionabLee
判断边数是否为4的倍数

#include <iostream>
 
using namespace std;
 
int main()
{
    int T;
    cin>>T;
    while(T--){
        int n;
        cin>>n;
        if(n%4==0)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

B.AccurateLee
举个例子:
000011001110001001001111111
将这个字符串分为三部分:
0000[110011100010010]1111111
中间的一系列1100、111000、100、10;形如10的串可以合并为1100、0、0、0;进而合并为0;
即[110011100010010]变为0;
所以,这个字符串最终变为0000[0]1111111;
可以发现,如果中间的[10]可以变成0,如果有的话,没有结果就是原串。

#include <iostream>
#include<string>
 
using namespace std;
 
int main()
{
    int T;
    cin>>T;
    while(T--){
        int n;
        string s;
        cin>>n>>s;
        int p1=0,p2=0;
        for(int i=0;i<n;i++){
            if(s[i]=='0')p1++;
            else break;
        }
        for(int i=n-1;i>=0;i--){
            if(s[i]=='1')p2++;
            else break;
        }
        string res="";
        bool t=false;
        if(p1+p2<n)t=true;
        while(p1--)res+="0";
        if(t)res+="0";
        while(p2--)res+="1";
        cout<<res<<endl;
    }
    return 0;
}

C.RationalLee
首先要知道,w为1的朋友,分到最大的数字;
将朋友按w排升序,数字按a排升序;
a从后往前,w从前往后,将数字给朋友,一人一个,这时每个朋友有了自己最大的数字,注意w==1的朋友,这时也有了自己最小数字;
然后,a从前往后,w后往前,将数字给朋友,每个人按w-1个发数字,发满就到下一个人,这样可以消耗小的数字;
最后,每个朋友有了自己最大的数字和最小的数字,计算结果即可。

#include<bits/stdc++.h>
 
using namespace std;
const int MAX_N=2e5+5;
typedef long long ll;
 
int n,k;
int a[MAX_N],h[MAX_N];
 
void solve(){
    sort(a,a+n);
    sort(h,h+k);
    ll res=0;
    for(int i=0;i<k;i++){
        res+=a[n-i-1];
        if(h[i]==1)res+=a[n-i-1];
    }
    int p=0;
    for(int i=k-1;i>=0;i--){
        if(h[i]==1)break;
        res+=a[p];
        p+=h[i]-1;
    }
    cout<<res<<endl;
}
 
int main()
{
    int T;
    cin>>T;
    while(T--){
        cin>>n>>k;
        for(int i=0;i<n;i++)scanf("%d",a+i);
        for(int i=0;i<k;i++)scanf("%d",h+i);
        solve();
    }
    return 0;
}

D.TediousLee
打表找规律:
n从1到20,结果为4的倍数,所以结果除4再观察如下:
0 0 1 1 3 6 12 24 49 97 195 390 780 1560 3121 6241 12483 24966 49932 99864;
可以发现如下规律,6个为一组,在前一结果的基础上:*2、*2、*2、*2+1、*2-1、*2+1
所以预处理所有结果即可。
关于如何打表:
写一个dfs计算以v为根的树的结果;
对于v的度d可能是0、1、3;
对于d为0,结果为0;
对于d为1,结果为子树的结果;
对于d为3,两个情况,一是v不染色,结果是3颗子树的和;二是v染色,那么v的子节点也染色,再计算下面有多少染色就可以了。
打表代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAX_N=2e6+5;
const int M=1e9+7;


int n;
int d[MAX_N];
int child[MAX_N][3];

void net(){
    int t=n;
    for(int i=0;i<t;i++){
        if(d[i]==0){
            child[i][0]=n++;
            d[i]++;
        }
        else if(d[i]==1){
            child[i][1]=n++;
            child[i][2]=n++;
            d[i]+=2;
        }
    }
}

int dfs(int v){
    if(d[v]==0)return 0;
    if(d[v]==1)return dfs(child[v][0]);
    int res1=0;
    for(int i=0;i<3;i++)res1+=dfs(child[v][i]);
    int res2=4;
    for(int i=0;i<3;i++){
        for(int j=0;j<d[child[v][i]];j++){
            res2+=dfs(child[child[v][i]][j]);
        }
    }
    return max(res1,res2);
}

void get(){
    int res=dfs(0);
    cout<<res/4<<endl;
}

void da(){
    n=1;
    for(int i=1;i<=20;i++){
        cout<<i<<":";
        get();
        net();
    }
}

int main()
{
    da();
    return 0;
}

ac代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAX_N=2e6+5;
const int M=1e9+7;

int res[MAX_N];

int main()
{
    res[1]=res[2]=0;
    res[3]=res[4]=1;res[5]=3;
    for(int i=6;i<=2e6;i++){
        res[i]=(ll)res[i-1]*2%M;
        if((i-6)%6==3||(i-6)%6==5)res[i]=((ll)res[i]+1)%M;
        else if((i-6)%6==4)res[i]=((ll)res[i]-1+M)%M;
    }
    int T;
    cin>>T;
    while(T--){
        int n;
        cin>>n;
        cout<<(ll)res[n]*4%M<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值