“蔚来杯“2022牛客暑期多校训练营2 补题题解(C 、D 、G 、H 、J 、K 、L)


觉得有帮助的点个赞!

比赛地址
参考的大佬题解

C Link with Nim Game

请添加图片描述

#include<bits/stdc++.h>

using namespace std;

#define int long long 

const int N = 2e5 + 10;

int T, n, m;
int a[N];  //记录石子值
int num;  //记录石子异或和
int sum;  //记录石子总数
int ans;  //记录答案  

signed main()
{
   
	cin>>T;
	while(T -- ){
   
		cin>>n;
		num = 0, sum = 0;
		ans = 0;
		//读入石子堆,计算所有石子的异或和、数量和 
		for(int i = 1; i <= n; i ++ ){
   
			cin>>a[i];
			num ^= a[i];
			sum += a[i];
		} 

		if(num){
     //如果石子异或和不为0,先手只需要保证每次操作把石子的异或和置为0即可,所以这种情况下,先手必胜
			int maxv = 0;
			for(int i = 1; i <= n; i ++ ){
     //找到能去除的最大石子数
				int t = a[i] - (num ^ a[i]);  //从a[i]中取出t颗石子可以让所有石子堆异或和为0
				maxv = max(t, maxv);  //记录最大的t值 
			}
			for(int i = 1; i <= n; i ++ ){
     //找第一步有几个可以的方案 
				int t = a[i] - (num ^ a[i]);  //从a[i]中取出t颗石子可以让所有石子堆异或和为0
				if(t == maxv) ans ++ ;  //在某一堆石子中拿走maxv个石子,有几堆合适的就哪有几种操作数
			} 
			cout<<sum - maxv + 1<<' '<<ans<<endl;  //输出回合数和操作种类(有几个符合的石子堆就是可以从几个石子堆中拿走石子,就是有几种操作)
		}
		else{
     //先手必败 
			set<int>S, tt;
			//记录每堆石子被Alice拿走一个石子之后的情况
			for(int i = 1; i <= n; i ++ ){
   
				int t = a[i] ^ (a[i] - 1);  //记录所有在第a[i]堆中取出一个石头后剩下的石子堆异或和的情况 
				S.insert(t);  //记录在集合中 
			}
			for(auto x : S){
     //遍历所有 每堆石子被Alice拿走一个石子之后的情况
				for(int i = 1; i <= n; i ++ ){
     //对于第i堆石子
					//下一步就是把a[i]变为a[i]^x 
					int t = a[i] ^ x;  //在第a[i]堆中取出1个石头 此时sum=x,我们想要sum重新变为0,需要让a[i]变成a[i] ^ x,这样才能抵消x
					if(a[i] - t > 1){
     //这一步就是对于a[i],需要拿走多少块可以让所有石子异或和为0,如果大于1,这个方案应该去除
						tt.insert(x);  // 如果剩余个数不为1,那么这个x需要删除,说明这种情况不行,后续要去除 
					}
				}
			}
			for(auto op : tt) S.erase(op);  //遍历去除不合适的情况 
			//第一轮可能的操作数就是取1后下一步必须取1的堆的数量
			for(int i = 1; i <= n; ++ i) if(S.count(a[i] ^ (a[i] - 1))) ans ++ ;
			cout<<sum<<' '<<ans<<endl;
		}
	}
	return 0;
} 

D Link with Game Glitch

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值