Codeforces Round 784 (Div. 4)

本场小结:
1.对于一些奇怪的题目我们一定要去找存在哪些性质,构造题目和模拟题目同样也是发现性质之后尝试使用暴力枚举
2.双指针的时候注意取结果的位置有时候用while比for更好
3.对于位运算符的出现我们一定要考虑是否具有拆位的性质,区间的也要考虑是否可以使用RMQ的性质

目录

A. Division?

B. Triple

C. Odd/Even Increments

D. Colorful Stamp

E. 2-Letter Strings

F. Eating Candies

G. Fall Down

H. Maximal AND


A. Division?

题目意思:判断每个数所在的区间即可,输出对应语句

直接模拟即可

void solve()
{
    cin>>n;
    if(n<1400) cout<<"Division 4"<<endl;
    else if(n<1600) cout<<"Division 3"<<endl;
    else if(n<1900) cout<<"Division 2"<<endl;
    else cout<<"Division 1"<<endl;

    return ;
}


B. Triple


题目意思:给定一个包含 n 元素的数组 a,输出至少出现三次的任何值,如果没有这样的值,则输出 -1。

考虑数据范围直接用map存储即可

void solve()
{
    mp.clear();
    cin>>n;
    int ans=0;
    while(n--){
        int x; cin>>x;
        mp[x]++;
        if(mp[x]>=3) ans=x;
    }
    if(!ans) ans=-1;
    cout<<ans<<endl;
    
    return ;
}


C. Odd/Even Increments


题目意思:对于一个序列一次操作可以对于所有的奇数索引+1 或者所有偶数索引+1,问是否可以是的最后所有数奇偶性相同

直接判断对于奇数或者偶数的索引个是否都是属于同一种奇偶性即可

void solve()
{
    cin>>n;
    int cnt1=0,cnt2=0,ans1=0,ans2=0;
    for(int i=1;i<=n;i++){
        int x; cin>>x;
        if(i&1){
            if(x%2) cnt1++;
            else cnt2++;
        }
        else{
            if(x%2) ans1++;
            else ans2++;
        }
    }
    if(ans1*ans2+cnt1*cnt2==0) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
 
    
    return ;
}


D. Colorful Stamp


题目意思:有n 个点,最初都为白色。每次染色可将相邻的两个点染成红色与蓝色,或染成蓝色与红色。每次染色会将之前的颜色覆盖掉,问给出的颜色组合是否能通过用这种染色方式染色出来。

我们会发现无论怎么染色两个白色中间都不可能全是一种颜色,用双指针来处理即可,对于一个我们直接特判,可以设置边界哨兵便于处理

char s[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>s[i];
    s[0]=s[n+1]='W';
    if(n==1){
        if(s[1]=='W') cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        return ;
    }
    for(int i=1;i<=n;i++){
       
        
        if(s[i-1]=='W'&&s[i+1]=='W'&&s[i]!='W'){
            cout<<"NO"<<endl;
            return ;
        }
        int cnt=0,j=i;
        while(j<=n&&s[j]==s[i]) j++,cnt++;
        if(cnt&&s[i]!='W'){
            if(s[i-1]=='W'&&s[j]=='W'){
                cout<<"NO"<<endl;
                return ;
            }
        }
        if(i!=j) i=j-1;
    }    
    cout<<"YES"<<endl;
    
 
    
    return ;
}



E. 2-Letter Strings

题目意思:给定你n个字符长度为2的字符串,求一对中只有一个不一样的数量

我们可以考虑直接使用枚举当前这个位置的一个位置同时另一个位置不同即可

void solve()
{
    cin>>n;
    vector<vector<int>> cnt(12,vector<int>(12,0));
    LL ans=0;
    for(int i=1;i<=n;i++){
        string s; cin>>s;
        for(int j=0;j<2;j++){
            for(char  k='a';k<='k';k++){
                if(k==s[j]) continue;
                string a=s; a[j]=k;
                ans+=cnt[a[0]-'a'][a[1]-'a'];    
            }
        }
        cnt[s[0]-'a'][s[1]-'a']++;
    }
    cout<<ans<<endl;
        return ;
}


F. Eating Candies

题目意思:两个人从序列两边开始移动求想等时两个人可以总共移动的最多的数目

明显的左右两边同时移动考虑双指针有时候使用while会好写一点

LL t,n,m;
LL a[N],b[N],c[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    LL ans1=a[1],ans2=a[n],ans=0;
    int l=1,r=n;
    while(l<r){
        if(ans1==ans2){
            ans=max(ans,l+n-r+1);
        }
        if(ans1<=ans2){
            l++;
            ans1+=a[l];
        }
        else if(ans2<ans1){
            r--;
            ans2+=a[r];
        }
    }
    cout<<ans<<endl;
        return ;
}


G. Fall Down

模拟题寻找性质

题目意思:n x m 的网格是障碍物和羽毛球和空气,障碍物是固定不会动的羽毛球会在空气中下落下求最后状态

对于模拟题就要去找性质,首先数据范围不是很大我们可以考虑稍微暴力的写法,我们发现肯定是要从上而下的来枚举下降的方式然后判断是不是可以下降的即可

char g[M][M];
void solve()
{
    cin>>n>>m;
    memset(g,0,sizeof g);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
        cin>>g[i][j];
    }
    
    for(int j=1;j<=m;j++){
        for(int i=n-1;i>=1;i--){
            if(g[i][j]=='*'){
                if(g[i+1][j]=='o'||g[i+1][j]=='*') continue;
                int q=i;
                while(g[q+1][j]=='.'){
                    swap(g[q+1][j],g[q][j]);
                    q++;
                }
            }
        }
    }
     for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
        cout<<g[i][j];
        cout<<endl;
    }
    cout<<endl;
    
        return ;
}



H. Maximal AND


按位与操作中常用拆位
我们考虑从最大的数位开始枚举如果这个位置可以没有0的填上0之后大家都是1那一定
是优的否则就不填这一位
应该熟记^可以使用前缀和,|可以使用RMQ,&使用拆位

 

int sum[35];
int a[N];
void solve()
{
    cin>>n>>m;
    memset(sum,0,sizeof sum);
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
        for(int j=0;j<=30;j++){
            if(a[i]>>j&1) ;
            else sum[j]++;
        }
    }
    int ans=0;
    for(int i=30;i>=0;i--){
        if(m>=sum[i]){
            ans|=(1<<i);
            m-=sum[i];
        }
    }
    cout<<ans<<endl;
        return ;
}

  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值