(mathcal{Description})
复杂度要求(O(n))
(mathcal{Solution})
有一个显而易见的定理
- 在中间过程若(A)让(B)往前移动,那么之后两者都是只让对方往前移动
- 若自己往前移动,那么两者都是只往前移动
因为都采用最优策略,所以两个人不会乱搞
如果选择让对方移动肯定是让对方移动到一个对对方来说不利的情况
那么对方肯定会让自己变回原来的状态
状态是指最后两者每个人会走过的站点
也就是会由原本都是自己往前走变成你拉我往前走,然后我拉你往前走
于是可以认为,两个人都只能往前移动,金币按照区域平分
并且有一个人有一次(pass)的机会
也就是他们中有一人可以让自己的区域变少一并让对方的区域变多一
这取决于第一次(Jack)做的决定是什么(让自己往前走/让(Rose)往前走)
如果什么都不做那么最后相遇的点是在与(frac{n}{2})的差不超过1的位置
最后相遇到底会是哪个格子也是看谁拥有(pass)机会
另外,他们两人一定有办法使最终状态达到上面所说状态,所以按以上方法能赢的人一定会赢,不能赢能平则一定会平,否则就会输
所以按(n)分奇偶讨论即可
(mathcal{Code})
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年08月28日 星期三 09时39分38秒
*******************************/
#include <cstdio>
#include <fstream>
#include <algorithm>
using namespace std;
const int maxn = 10005;
//{{{cin
struct IO{
template<typename T>
IO & operator>>(T&res){
res=0;
bool flag=false;
char ch;
while((ch=getchar())>'9'||ch<'0') flag|=ch=='-';
while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
if (flag) res=~res+1;
return *this;
}
}cin;
//}}}
int T,n;
int a[maxn],l[maxn],r[maxn];
int main()
{
cin>>T;
while (T--){
cin>>n;
for (int i=1;i<=n;++i) cin>>a[i];
l[0]=r[n+1]=0;
for (int i=1;i<=n;++i) l[i]=l[i-1]+a[i];
for (int i=n;i>=1;--i) r[i]=r[i+1]+a[i];
int x=n/2,y=x+1,z=y+1;
if (n==1) printf("tie
");
else if (n&1){
if ((l[x]>r[x]&&l[y]>r[y])||(l[y]>r[y]&&l[z]>r[z])) printf("win
");
else if ((l[x]>=r[x]&&l[y]>=r[y])||(l[y]>=r[y]&&l[z]>=r[z])) printf("tie
");
else printf("lose
");
}
else{
if (l[x]>r[x]||l[y]>r[y]) printf("win
");
else if (l[x]>=r[x]||l[y]>=r[y]) printf("tie
");
else printf("lose
");
}
}
return 0;
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧