- 按道理是应该用贪心的思想去做(实验的时候也是这样的),但是我们可以换种思路,通过实验然后对原数组不变(不需要移除元素),进行1. 数组折半后的奇数偶数。2. 相同堆有几对。3. 如果是奇数要易主。 4. 如果two==2 或者 cnt[i]==3铁定自己输对方赢。来通过这些规律来判断。
#include <bits/stdc++.h>
using namespace std;
string solve(vector<int>& stones){
unordered_map<int,int> cnt;//存储数量
int two = 0;// 有两个堆石子相等的对数
bool x = stones.size()/2 & 1; //默认我的赢家为x(这个和石子堆的奇数偶数性质有关(总结出来的))
for(int i :stones){
cnt[i]++;//记录堆中相同数量堆的出现次数
if(cnt[i]==2) two++;//出现了一对,所以加1
// two==2(有两堆相同的了), 先手无论如何取,第一次取完最少仍有一组石子数相同的石堆
// cnt[i]==3同理(有三个数都同了,那么必然2个数相同),因此先手输,woman赢
if(two==2||cnt[i]==3){
return "woman";
}
if(i&1) x = !x;//如果遇到奇数个石头,进行转换。赢家(规律总结)
}
return x? "man" : "woman";
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
vector<int> stones(n);//初始化方式值得学习
//注意,根据规则,所有都是0,必输
bool isAllZero = true;
for(int i =0; i <n; i++){
cin>>stones[i];
//注意,根据规则,如果遇到一个不是0
if(stones[i]) isAllZero =false;
}
if(isAllZero){
cout<<"woman"<<endl;
}else{
cout<<solve(stones)<<endl;
}
}
return 0;
}