Codeforces Round 784 (Div. 4)题解 ABCDEFGH

A. Division?

题意:给你一个等级分,输出它属于哪个等级。

思路:模拟即可

    int k;
	cin>>k;
	if(k>=1900){
		cout<<"Division 1"<<endl;
	}
	else if(k>=1600){
		cout<<"Division 2"<<endl;
	}
	else if(k>=1400){
		cout<<"Division 3"<<endl;
	}
	else{
		cout<<"Division 4"<<endl;
	}

B. Triple

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

思路:开一个cnt或者map模拟即可

    int k;
	cin>>k;
	map<int,int>mp;
	int a[k+1];
	for(int i=1;i<=k;i++){
		int x;
		cin>>x;
		a[i]=x;
		mp[x]++;
	}
	sort(a+1,a+k+1);
	unique(a+1,a+k+1);
	int l=unique(a+1,a+k+1)-a-1;
	for(int i=1;i<=l;i++){
		if(mp[a[i]]>=3){
			cout<<a[i]<<endl;
			return ;
		}
	}
		cout<<-1<<endl;

C. Odd/Even Increments

题意:给定一个长为 n 数组 a=[a1​,a2​,a3​⋅⋅⋅⋅,an​] ,您可以对其进行两种类型的操作:

1.将 1 添加到具有奇数索引的每个元素。换句话说,改变数组如下:a1​=a1​+1,a3​=a3​+1,a5​=a5​+1,......

2.将 1 添加到具有偶数索引的每个元素。换句话说,改变数组如下:a2​=a2​+1,a4​=a4​+1,a6​=a6​+1,......

确定经过任意次数的操作后,是否有可能使最终数组仅包含偶数或仅包含奇数。换句话说,确定是否可以使数组的所有元素在经过任意次数的操作后具有相同的奇偶性。

思路:发现修改会导致所有 i&1 的位置发生改变,在初始的时候判断奇偶上是否一致即可

    int n;
	cin >> n;
	for(int i = 1;i<=n;i++)cin >>q[i];
	int j1=0,j2=0,o1=0,o2=0;
	for(int i = 1;i<=n;i++){
		if(i&1){
			if(q[i]&1)j1++;
			else j2++;
		}
		else{
			if(q[i]&1)o1++;
            else o2++;
		}
	}
	bool f = false;
	if(j1 && !j2||!j1 && j2 || !j1 && !j2){
		if(o1 && !o2||!o1 && o2 || !o1 && !o2)f = true;
	}
	if(f)cout <<"YES"<<endl;
	else cout <<"NO"<<endl;

D. Colorful Stamp

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

思路:可以发现能够染出任意的蓝红,所以每次遇到白色判断二者是不是都有,然后更新即可

    int n;
	cin >> n;
	string s;
	cin >> s;
	int b = 0,r = 0;
	for(int i =0;i<n;i++){
		if(s[i] =='B')b++;
		if(s[i]=='R')r++;
		if(s[i] =='W'){
			if(!r && b || !b && r){
				break;
			}
			if(r && b){
				r = 0,b=0;
			}
		}
	}
	if(!b && r || !r && b){
		cout <<"NO\n";
	}
	
	else cout <<"YES\n";

E. 2-Letter Strings

题意:你被给予了n个长度为2的字符串,每个含有从a到k的小写字母。找出所有对(i,j)使得i<j并且第i个字符串和第j个字符串刚好有1个字符不同。

思路:遍历一遍,对于每个s,求某一位相等,而另一位不相等的字符串个数。两种情况无重复,直接枚举不相等的那位是什么字符,累加答案

    LL ans = 0;
	memset(q , 0 , sizeof q);
	int n;
	cin >> n;
	for(int i = 0;i<n;i++){
		string s;
		cin >> s;
		q[s[0] -'a'][s[1] -'a']++;
		for(int j = 0;j<11;j++){
			if(q[j][s[1]-'a'] > 0 && j!=s[0]-'a'){
				ans+=q[j][s[1]-'a'];
			}
			if(q[s[0]-'a'][j]>0 && j!= s[1] -'a'){
				ans+=q[s[0]-'a'][j];
			}
		}
	}
	cout << ans << endl;

F. Eating Candies

题意:有 n 个糖果从左往右放在桌子上, Alice 和 Bob 吃糖果, Alice可以从左边开始吃, Bob可以从右边开始吃,他们需要连续吃,不能跳过任何一颗糖果,如果 Alice 吃掉了糖果, Bob 就不能吃,反之亦然,他们的目标是吃到等重的糖果。对于每组测试样例,输出一个整数,表示他们同时能吃到的最多糖果数

思路:直接使用双指针+贪心,分前后开始吃,谁小谁吃,非空相等让其中一个吃即可。最后判断一下。

    deque<int> q;
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
        int a;
		cin>>a;
		q.push_back(a);
	}
	int alice=0,bob=0,ar=0,br=0;
	int ans=0;
	while(!q.empty()){
		if(alice==bob){
			ans=ar+br;
			alice+=q.front();
			ar++;
			q.pop_front();
		}
		else if(alice<bob){
			alice+=q.front();
			q.pop_front();
			ar++;
		}
		else{
			bob+=q.back();
			q.pop_back();
			br++;
		}
	}
	if(alice==bob) ans=ar+br;
	cout<<ans<<endl;

G. Fall Down

题意:

有一个 n×m 的网格(1≤n,m≤50),其中每个格子上有三种情况:

  1. * 字符:此块为一个石子。
  2. o 字符:此块为障碍物,石子不能通过。
  3. . 字符:此块为空,石子可以通过。

每块石子会往下落,直到它落在了网格最下面一行、障碍物的上面一格或已落下的石子上面一格。

给出原始网格,求石子落下后的网格。

思路:超级模拟题,对于每一列,o上边的落到o,o下边的落到底。

甚至不需要dfs

int n,k;
cin>>n>>k;
char a[51][51];
for(int i=1;i<=n;i++){
	for(int j=1;j<=k;j++){
		cin >> a[i][j];
	}
}
for(int i=1;i<=k;i++){
	for(int j=n-1;j>=1;j--){
		if(a[j][i]=='*'){
			if(a[j+1][i]=='o'||a[j+1][i]=='*'){
				continue;
			}
			else if(a[j+1][i]=='.'){
				for(int m=j+1;m<=n;m++){
					if(a[m][i]=='o'||a[m][i]=='*'){
						swap(a[m-1][i],a[j][i]);
						break;
					}
					if(m==n){
						swap(a[n][i],a[j][i]);
					}
				}
			}
		}
	}
}
for(int i=1;i<=n;i++){
	for(int j=1;j<=k;j++){
		cout<<a[i][j];
	}
	cout<<endl;
}

H. Maximal AND

题意:

让 AND 表示按位与, OR 表示按位或

你有一个长度为 n 的数组 a 和一个非负整数 k 。你可以在 a 数组上做以下操作:

  • 选出一个下标 i (1≤i≤n),将 ai​ 替换为 ai​ OR 2j (0≤j≤30)。也就是说将二进制下的 ai​ 的第 j 位赋为 1 。

最多做 k 次操作。

输出操作后 a1​ AND a2​ AND…AND an​ 的最大值。

思路:考虑按位与运算的性质,先要尽量把高位统一修改为 1。

统计修改每一位全部为 1 需要花费的操作次数 cnt_i,从高位修改。如果当前需要的修改次数大于可操作次数,则当前位为 0。

    int ans=0;
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=0;i<=30;i++){
        for(int j=1;j<=n;j++) {
            if(!((a[j]>>i)&1)) cnt[i]++;
        }
    }
    for(int i=30;i>=0;i--) {
        if(k>=cnt[i]){
            k-=cnt[i];
            ans+=(1<<i);
        }
    }
    cout<<ans<<endl;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值