CodeForces - 1669 C-H

C. Odd/Even Increments

在这里插入图片描述
在这里插入图片描述
#题意:
给定一个长为 n 数组
确定经过任意次数的操作后,是否有可能使最终数组仅包含偶数或仅包含奇数。换句话说,确定是否可以使数组的所有元素在经过任意次数的操作后具有相同的奇偶性。
请注意,您可以多次执行这两种类型的操作(甚至没有)。不同类型的操作可以执行不同的次数。
#思路:只要原数组奇数位和偶数位保证相同的奇偶性就能实现否则就不行

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;cin>>t;
    while(t--)
    {
        int n,x;cin>>n;
        map<int,int>mpa,mpb;//分别记录奇数下标和偶数下标
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            if(i%2==1) mpa[x&1]++;//将对于数组下标的数据的奇偶性进行分别存储
            else mpb[x&1]++;
        }
        if(mpa.size()==1&&mpb.size()==1)  cout<<"YES"<<endl;//如果对应位置奇偶性相同那么对于的map容器的键值对只有1
        else cout<<"NO"<<endl;
    }
    return 0;
}

D. Colorful Stamp

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题意:给定一个长度为n的字符串,字符串初始由字符“W”组成。可以对字符串染色将这个字符串中的两个连续的字符染色成“RB”或者“BR”,可以重复染色。
判断这个字符串能不能通过若干次染色从初始状态染色成这个状态。
思路:由于染色只能一次染色两个那么不会出现W与W之间夹着纯B或者纯R的情况
只需要考虑W到W之间是都出现单一的R或者B即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t; cin>>t;
    while(t--){
        int n,flag=1;cin>>n;
        string s; cin>>s;
        for(int i=0;i<s.size();i++){
            if(s[i]!='W'){
                int j=i;
                map<char,int>mp;
                while(j<s.size()&&s[j]!='W') mp[s[j]]++,j++;//使用map容器判断W到W之间是否只有一种字符,如果是则不能染色
                if(mp.size()==1) flag=0;
                i=j;
            }
        }
        if(flag) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

E. 2-Letter Strings

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
#题意:就是说给定的由两个字符组成的字符串有多少对是只有一个字符相同的
#思路:字符只有a-z,并且只有一个字符串只有两个字符,直接暴力遍历求解,每次固定一个字符不变,改变另外一个查看有没有一样的字符暴力遍历即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[27][27];
int main(){
    int t;cin>>t;
    while(t--){
        ll n,ans=0;cin>>n;
        memset(a,0,sizeof(a));//每次初始化数组a
        for(int i=0;i<n;i++){
            string s1;cin>>s1;
            for(int j=0;j<2;j++)
                for(char c='a';c<='k';c++){
                    if(c==s1[j]) continue;
                    string s2=s1;s2[j]=c;//固定一个字符不变,改变另外一个看有没有相同的字符
                    ans+=a[s2[0]-'a'][s2[1]-'a'];
                }
            a[s1[0]-'a'][s1[1]-'a']++;
        }
        cout<<ans<<endl;
    }
}

F. Eating Candies

在这里插入图片描述
在这里插入图片描述
#题意:有两个人分别从左右两端吃糖果,要保证在两个人吃的糖果重量相同的情况下吃尽可能多的糖果,并且不能跳着吃,求能吃的最多糖果
#思路:由于两个人是从左右两遍分别开始吃并且不能跳过,可以使用双指针进行模拟。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;cin>>t;
    while(t--){
        int n,a[200006];cin>>n;
        for (int i=1;i<=n;i++)cin>>a[i];
        int i=1,j=n,ans=0,w1=0,x1=0,w2=0,x2=0;
        while (i<=j){//使用双指针分别从两端开始走,走到i>j时结束
            if(w1<w2){
                x1++;w1 += a[i];i++;//每次根据两个人吃的重量进行指针移动
            }
            if (w2<w1){
                x2++;w2 += a[j];j--;
            }
            if (w1==w2){
                if(x1+x2>ans)ans=x1+x2;//有更多的糖果数后更新最大值
                w2+=a[j];j--;x2++;
            }
        }
        cout<<ans<<endl;
    }
}

G. Fall Down

在这里插入图片描述
在这里插入图片描述
题意:给一个图“ * ”代表石头"o"代表障碍物 石头遇见障碍物会停止掉落
思路:模拟石头下落的过程,遇见障碍物就停下。

#include <bits/stdc++.h>
using namespace std;
int main(){
    int t;cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        char a[n][m];
        for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j];//读入图形
        for(int i=0;i<m;i++){
            int last=n-1;
            for(int j=n-1;j>=0;j--){
                if(a[j][i]=='o')last=j-1;//遇见石头
                else if(a[j][i]=='*'){//模拟下落过程
                    swap(a[j][i],a[last][i]);
                    last--;
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)cout<<a[i][j];
            cout<<endl;
        }
    }
    return 0;
}

H. Maximal AND

在这里插入图片描述
在这里插入图片描述
#题意:给 n, k 让你进行最多k次操作 使得整个数组 & 操作得到最大值
关于每次操作 你可以改变数组中某个数的某个二进制位变为 1
#思路:先统计 二进制中 0-30 位每位有多少个 1,要想 & 运算取得最大值我们需要尽可能的把 高位 统一为 1 ,贪心从最高位开始遍历,如果剩余的次数大于等于 该位不是1的个数,就可以加上该位的二进制数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[31];
int main(){
    int t;cin>>t;
    while(t--){
        ll n,k;cin>>n>>k;
        memset(a,0,sizeof(a));//初始化数组
        for(int i=0;i<n;i++){
           ll m;cin>>m;
           int cnt=0;
           while(m>0){//进行统计数组中各个数的二进制里面的1
               if(m&1) a[cnt]++;
               m/=2;
               cnt++;
           }
        }
        ll sum=0;
        for(int i=30; i>=0;i--){//从最高位开始遍历使得同二进制位全为1
            if(k-(n-a[i])>=0&&n!=a[i])
                k-=(n-a[i]),a[i]=n;
        }
        for(int i=30;i>=0;i--) if(a[i]==n) sum+=pow(2, i);//遍历求和
        cout<<sum<<endl;
    }
    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值