卧薪尝胆,厚积薄发。
CQOI2013 新Nim游戏
Date: Mon Nov 12 20:01:32 CST 2018 In Category: NoCategory

Description:

给你 $n$ 堆火柴,后手先拿走一些火柴,然后先手拿,先手操作,要求让后手拿走尽量少的火柴使得先手不能赢。
$1\leqslant n\leqslant 100$

Solution:

首先由尼姆游戏得这个其实就是要求最后不能选出来几个使得他们异或和为 $0$ ,那么我们就能想到线性基,也就是说最后判断一下如果被削成零了那他就不能插入,关于怎样让拿走的火柴尽量少,发现最后拿走的火柴堆数是一定的,也就是说这是一个拟阵,那么只要从大到小排个序一个一个判断就行了。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
int n;
#define MAXN 110
int s[MAXN];
struct LinearBase
{
int d[30];
bool insert(int x)
{
for(int i = 30;i >= 0;--i)
{
if((x >> i) & 1)
{
if(d[i] == 0)
{
d[i] = x;
return true;
}
else
{
x ^= d[i];
}
}
}
return false;
}
}g;
bool cmp_s(int a,int b){return a > b;}
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)scanf("%d",&s[i]);
sort(s + 1,s + 1 + n,cmp_s);
long long ans = 0;
for(int i = 1;i <= n;++i)
{
if(!g.insert(s[i]))ans += s[i];
}
cout << ans << endl;
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡