长着一张博弈脸的搜索题。给出n*m的地图,有石头空地若干,还有一个宝藏。正整数表示石头的hp,0表示空地,-1表示宝藏,而且保证只有一个。AB轮流敲,每次从边界开始,选一个可达的石头,敲一下,石头的hp-1,hp为零就变成空地了。谁先敲到宝藏,谁赢。
如果从边界直接能走到宝藏,那么先手的A就赢了。否则呢,就会有一层石头保护着宝藏,谁先打破保护层,谁就输。所以保护层外的石头加上保护层边界上每个石头的hp-1就构成了他们能敲的石头总数。就是说把保护层边界上的各个点的hp都只剩下1。
5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 0 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0
5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 1 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0
5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 2 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0
这三组数据改变了我企图一遍bfs的想法。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<string> #include<queue> #include<cmath> #include<map> ///LOOP #define REP(i, n) for(int i = 0; i < n; i++) #define FF(i, a, b) for(int i = a; i < b; i++) #define FFF(i, a, b) for(int i = a; i <= b; i++) #define FD(i, a, b) for(int i = a - 1; i >= b; i--) #define FDD(i, a, b) for(int i = a; i >= b; i--) ///INPUT #define RI(n) scanf("%d", &n) #define RII(n, m) scanf("%d%d", &n, &m) #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k) #define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p) #define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q) #define RFI(n) scanf("%lf", &n) #define RFII(n, m) scanf("%lf%lf", &n, &m) #define RFIII(n, m, k) scanf("%lf%lf%lf", &n, &m, &k) #define RFIV(n, m, k, p) scanf("%lf%lf%lf%lf", &n, &m, &k, &p) #define RS(s) scanf("%s", s) ///OUTPUT #define PN printf(" ") #define PI(n) printf("%d ", n) #define PIS(n) printf("%d ", n) #define PS(s) printf("%s ", s) #define PSS(s) printf("%s ", s) #define PC(n) printf("Case %d: ", n) ///OTHER #define PB(x) push_back(x) #define CLR(a, b) memset(a, b, sizeof(a)) #define CPY(a, b) memcpy(a, b, sizeof(b)) #define display(A, n, m) {REP(i, n){REP(j, m)PIS(A[i][j]);PN;}} #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 using namespace std; typedef long long LL; typedef pair<int, int> P; const int MOD = 1e9+7; const int INFI = 1e9 * 2; const LL LINFI = 1e17; const double eps = 1e-6; const double pi = acos(-1.0); const int N = 333; const int M = 888; const int move[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1}; struct point { int x, y; point(){}; point(int a, int b){x = a, y = b;}; }p; int a[N][N], vis[N][N]; int n, m, ans; queue<point> q; void bfs2() { int tx, ty; while(!q.empty())q.pop(); q.push(point(0, 0)); while(!q.empty()) { p = q.front(); q.pop(); REP(i, 4) { tx = p.x + move[i][0]; ty = p.y + move[i][1]; if(tx < 0 || ty < 0 || tx > n + 1 || ty > m + 1)continue; if(!vis[tx][ty]) { vis[tx][ty] = 2; ans += a[tx][ty]; q.push(point(tx, ty)); } else if(vis[tx][ty] == 1) { vis[tx][ty] = 2; ans += (a[tx][ty] - 1); } } } } bool bfs() { int tx, ty; while(!q.empty()) { p = q.front(); q.pop(); REP(i, 4) { tx = p.x + move[i][0]; ty = p.y + move[i][1]; if(tx <= 0 || ty <= 0 || tx > n || ty > m)return 0; if(!vis[tx][ty]) { vis[tx][ty] = 1; if(!a[tx][ty])q.push(point(tx, ty)); } } } bfs2(); return 1; } int main() { //freopen("input.txt", "r", stdin); int x, y; while(RII(n, m) != EOF) { ans = 0; CLR(a, 0); CLR(vis, 0); FFF(i, 1, n)FFF(j, 1, m) { RI(a[i][j]); if(a[i][j] == -1)x = i, y = j; } while(!q.empty())q.pop(); q.push(point(x, y)); vis[x][y] = 1; if(bfs())puts((ans & 1) ? "Ali Win" : "Baba Win"); else puts("Ali Win"); } return 0; }