NC51090. 新Nim游戏
描述
输入描述
第一行为整数k。即火柴堆数。第二行包含k个不超过109的正整数,即各堆的火柴个数。
输出描述
输出第一回合拿的火柴数目的最小值。如果不能保证取胜,输出-1。
示例1
输入:
6 5 5 6 6 5 5
输出:
21
C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-05-21 23:14:43
#include<bits/stdc++.h> using namespace std; #define ll long long const int N = 2e5 + 100; int a[N], d[N]; int main() { int n; cin >> n;//n堆火柴 ll ans = 0; for (int i = 1; i <= n; i++) cin >> a[i], ans += a[i];//初始化并求出所有火柴的根数 sort(a + 1, a + 1 + n, greater<int>());//按火柴的根数从大到小排列,采取贪心策略 for (int i = 1; i <= n; i++) { int x = a[i]; for (int i = 30; i >= 0; i--)//构造线性基 { if (x >> i & 1) { if (d[i]) x ^= d[i]; else { d[i] = x;//将x插入到线性基集合中 break; } } } if (x) ans -= a[i];//a[i]在线性基集合里面,那么总和就减去a[i] } cout << ans << endl; return 0; }
C++ 解法, 执行用时: 5ms, 内存消耗: 468K, 提交时间: 2022-04-21 17:38:49
#include<bits/stdc++.h> using namespace std; int n,a[101],d[31]; long long ans; int main(){ cin>>n; for(int i=1;i<=n;++i)cin>>a[i]; sort(a+1,a+n+1); for(int x=a[n];n;--n,x=a[n]){ for(int j=30;j>=0;j--)if((x>>j)&1){if(d[j])x^=d[j];else{d[j]=x;break;}} if(!x)ans+=a[n]; } cout<<ans; return 0; }