代码来自于蓝桥杯2021年第十二届省赛真题-异或数列_贾斯特比雷的博客-CSDN博客_蓝桥杯异或数列
思想讲的很清楚。
从最高位开始看,只有一个1必然先手胜,偶数个1必然在本位打平,因为优势会互相抵消掉(也可能互相给对方异或成0了,总之打平),奇数个1就要看本位0有多少个,a b互相抢最后的翻转权,如果是偶数个0则先手胜,否则后手胜
憨憨因为看不懂而自己加了一些注释
//2021省赛G-异或数列
#include
#include
//#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<=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<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)来解除cin
与cout
的绑定,进一步加快执行效率。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)