题意:给你三个数组A,B,C,三个数组长度相等,当中有一些位置可以进行(-1)操作,定义A+B=C为对于三个数组中的每个数都有a[i]+b[i]=c[i],先手想让A+B=C成立,后手不想让等式成立,如果当中某一时刻等式成立则先手胜,否则后手胜,问最后胜利者是谁;
首先在于如果要让A+B=C成立,那么每个位置都必须满足a[i]+b[i]=c[i],只要有任何一个地方不能满足,就可以直接输出后手赢。
对于每个位置,根据三个数是否能修改讨论,一共应当是8种情况,但可以等价化到6种(0+1=0优化成1+0=0,0+1=1优化为1+0=1);
然后这六种情况又会有四种结果:
1.固定状态,对应0+0=0的情况,如果a[i]+b[i]!=c[i]则返回0;
2.稳定状态,对于1+1=1以及(1+0=1且b[i]==0),也就是说减到最后可减的地方都变为0时等式依然成立,这种状态是稳定的;
3.脆弱状态,就是说在某一个时刻能够满足a[i]+b[i]=c[i],但再操作的话,就无法满足;
4.非法状态,直接返回0;
对于每个位置如果会到达脆弱状态,则记录步数weak[i],同时记录会到达脆弱状态的个数weakn;
如果会到达稳定状态,则记录到达稳定状态的步数的和stasum;
但是有一种情况需要特别照顾,就是上文稳定状态中提到的1+0=1,但b[i]!=0的情况。
1.a[i]+b[i]>c[i]+1,非法;
2.a[i]+b[i]==c[i]+1,也就是说必须一次操作就完成,所以这种状态在所有位置中只能最多出现一次,否则就return 0;
3.a[i]+b[i]<c[i],会达到脆弱状态。
具体看代码QAQ
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<string>
#include<set>
#include<algorithm>
#include<stack>
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int INF = 0x7fffffff;
typedef long long ll;
const double eps = 1e-8;
const double PI = 2 * cos(0.0);
const int MOD = 1000000007;
#define MAXN 101
int n;
int a[MAXN], ap[MAXN];
int b[MAXN], bp[MAXN];
int c[MAXN], cp[MAXN];
int weak[MAXN];
bool match()
{
mem(weak, 0);
int flag = 1;
int weakn = 0;
ll strsum = 0;
for (int i = 1; i <= n; i++)
{
int tmp = abs(a[i] + b[i] - c[i]);
if (!ap[i] && !bp[i] && !cp[i])
{
if (a[i] + b[i] != c[i]) return 0;
}
if (ap[i] && bp[i] && cp[i])
{
strsum += tmp;
}
else if (ap[i] && bp[i] && !cp[i])
{
if (a[i] + b[i] < c[i]) return 0;
if (!c[i]) strsum += tmp;
else weak[++weakn] = tmp;
}
else if (!ap[i] && !bp[i] && cp[i])
{
if (a[i] + b[i] > c[i]) return 0;
if (!a[i] && !b[i]) strsum += tmp;
else weak[++weakn] = tmp;
}
else if (ap[i] && !bp[i] && !cp[i])
{
if (a[i] + b[i] < c[i])return 0;
if (b[i] == c[i])strsum += tmp;
else weak[++weakn] = tmp;
}
else if (ap[i] && !bp[i] && cp[i])
{
if (!b[i])
{
strsum += tmp;
continue;
}
if (b[i]>c[i]) return 0;
if (a[i] + b[i] > c[i] + 1) return 0;
if (a[i] + b[i] == c[i] + 1)
{
if (!flag) return 0;
flag = 0;
}
tmp = c[i] - a[i] - b[i];
weak[++weakn] = tmp;
}
}
if (!weakn) return 1;
else if (weakn == 1)
{
if (strsum <= weak[1] + 1) return 1;
}
else if (weakn == 2)
{
if (strsum == 0)
{
if (abs(weak[1] - weak[2]) == 1) return 1;
}
else if (strsum == 1)
{
if (abs(weak[1] - weak[2]) == 0) return 0;
}
}
else
{
ll sum = strsum;
for (int i = 1; i <= n; i++)
{
sum += abs(weak[i]);
if (sum > 1) return 0;
}
return 1;
}
return 0;
}
int main()
{
int T;
cin >> T;
for (int kase = 1; kase <= T; kase++)
{
cin >> n;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) scanf("%d", &ap[i]);
for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
for (int i = 1; i <= n; i++) scanf("%d", &bp[i]);
for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
for (int i = 1; i <= n; i++) scanf("%d", &cp[i]);
for (int i = 1; i <= n; i++)
{
if (!a[i]) ap[i] = 0;
if (!b[i]) bp[i] = 0;
if (!c[i]) cp[i] = 0;
if (!ap[i] && bp[i])
{
swap(a[i], b[i]);
swap(ap[i], bp[i]);
}
}
printf("Case #%d: %s\n", kase, match() ? "Tweek" : "Craig");
}
}