类似FLOYED
就是用一个数组记录两个数字是否可以交战
头尾增加两个虚拟节点,处理比较方便
#include <cstdio>
#include <cstring>
const int MAXN = 100 + 12;
int beat[MAXN][MAXN];
bool map[MAXN][MAXN];
int a[MAXN];
int main()
{
int T;
int cas = 1;
scanf("%d", &T);
for(int i = 1; i <= T; i++)
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &beat[i][j]);
for(int i = 1; i <= n; i++) beat[0][i] = beat[n+1][i] = 0, beat[i][0] = beat[i][n+1] = 1;
memset(map, 0, sizeof(map));//map[i][j] 表示
for(int i = 0; i <= n + 1; i++) map[i][i+1] = map[i][i] = 1;//这两个有交战机会
for(int k = 2; k <= n; k++)
for(int i = 0; i <= n - k + 1; i++)
{
int j = i + k;
for(int l = i + 1; l <= j - 1; l++)
if(map[i][l] && map[l][j]) //起码是有交战机会
{
if(beat[i][l]) map[i][j] = 1;
if(beat[j][l]) map[i][j] = 1;
}
}
int ans = -1;
for(int i = 1; i <= n; i++)
if(map[0][i] && map[i][n+1] && a[i] > ans) ans = a[i];
printf("Case %d: %d\n", cas++, ans);
}
return 0;
}