【蓝桥杯】PREV-267 第十二届省赛G题 异或数列

 代码来自于蓝桥杯2021年第十二届省赛真题-异或数列_贾斯特比雷的博客-CSDN博客_蓝桥杯异或数列

 思想讲的很清楚。从最高位开始看,只有一个1必然先手胜,偶数个1必然在本位打平,因为优势会互相抵消掉(也可能互相给对方异或成0了,总之打平),奇数个1就要看本位0有多少个,a b互相抢最后的翻转权,如果是偶数个0则先手胜,否则后手胜

憨憨因为看不懂而自己加了一些注释

//2021省赛G-异或数列 
#include <iostream>
#include <cstring>
//#define rep(i,a,b) for(int i=(a);i<=(b);i++)
//#define _for(i,a,b) for(int i=(a);i<(b);i++)
using namespace std;
 
const int N = 200000+10;
int T,n,ans,a,b,sum;
int x[N],num[20+5];
 
void count()    //存储各位上1的个数 
{   
    sum=0;
    memset(num,0,sizeof(num));
//	rep(i,1,n)
	for(int i=1;i<=n;i++)
	{
		int xi=x[i];
		sum^=xi; 
		int pos=0;  
		while(xi){ 
			if(xi&1) num[pos]++; //从低位开始,按位与
			//比如xi为5,二进制101,5&1相当于 101&1,从低位开始与 
			pos++; //无论这一位是不是1 pos都++,也就是在相应为1的位上num才++ 
			xi>>=1; //右移一位再赋给xi,低位抛弃,高位补0 
			//右移相当于除以2,如5的二进制为101,右移之后为010,变成了2 
		}
	}
}
 
void solve(){
	count(); //计算各个位上的1有多少个 
	if(!sum){
		cout<<0<<endl;
		return;
	}
	else{
		for(int i=19;i>=0;i--){ //从高位开始看 
			int num0=n-num[i]; //本次n个数,num存储每位有几个1 num0为这一位有几个0 
			if(num[i]%2==0){ //这一位有偶数个1,这一位上a b必然打平 
				continue;
			}
			else if(num[i]==1){ //这一位只有一个1 先手胜 
				cout<<1<<endl;
				return;
			}
			else{ //如果这一位上有奇数个1 
				if(num0%2==0){ //有偶数个0,则先手胜 
					cout<<1<<endl;
					return;
				}
				else{ //否则后手胜 
					cout<<-1<<endl;
					return;
				}
			}
		} 
	}
	
    cout<<ans<<endl; //输出结果 
}
 
int main(){
	cin>>T;
	while(T--){
		cin>>n; //本次有n个数 
		//rep(i,1,n)
		for(int i=1;i<=n;i++)
		{
			cin>>x[i];
		}
		solve();
    }
	return 0;
} 

一点小tips,原博最后说的两个函数,查了一下,原因在l关于ios::sync_with_stdio(false);和 cin.tie(0)加速c++输入输出流_青梦丶的博客-CSDN博客_ios::sync_with_stdio(false);jjj

简单来说, 就是输入输出方面,使用cin cout要比scanf printf慢,这句话是用来略微加快速度的,但其实用完依旧慢,而且加完之后两种混用会出问题。

以下来自原博:

sync_with_stdio
这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起。

cin,cout之所以效率低,是因为先把要输出的东西存入缓冲区,再输出,导致效率降低,而这段语句可以来打消iostream的输入 输出缓存,可以节省许多时间,使效率与scanf与printf相差无几.

关于tie的解释来自关于ios::sync_with_stdio(false);和cin.tie(0);cout.tie(0);_绀香零八的博客-CSDN博客

以下来自原博:

tie是将两个stream绑定的函数,空参数的话返回当前的输出流指针。
在默认的情况下cin绑定的是cout,每次执行 << 操作符的时候都要调用flush,这样会增加IO负担。可以通过tie(0)(0表示NULL)来解除cincout的绑定,进一步加快执行效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值