// UVa 11405 - Can U Win? #include <iostream> #include <string> #include <string.h> #include <vector> #include <queue> using namespace std; int move[8][2] = { { 2, 1 }, { 2, -1 }, { -2, 1 }, { -2, -1 }, { 1, 2 }, { 1, -2 }, { -1, 2 }, { -1, -2 } }; struct state { int bits; int end; }; bool legal(char ch) { return ch == '.' || ch == 'P' || ch == 'k'; } int main() { int cases; for (cin >> cases; cases; cases--) { // read int m; cin >> m; string board[8]; getline(cin, board[0]); for (int i = 0; i < 8; i++) getline(cin, board[i]); // build edges int cost[64][64]; memset(cost, 127, sizeof(cost)); int oo = cost[0][0]; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) if (legal(board[i][j])) { for (int k = 0; k < 8; k++) { int a = i + move[k][0]; int b = j + move[k][1]; if (a >= 0 && a < 8 && b >= 0 && b < 8 && legal(board[a][b])) { cost[a * 8 + b][i * 8 + j] = 1; cost[i * 8 + j][a * 8 + b] = 1; } } } // Floyd's for (int k = 0; k < 64; k++) for (int i = 0; i < 64; i++) if (cost[i][k] != oo) for (int j = 0; j < 64; j++) if (cost[k][j] != oo && cost[i][j] > cost[i][k] + cost[k][j]) { cost[i][j] = cost[i][k] + cost[k][j]; } // get pawns int knight = 0; vector<int> pawn; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) if (board[i][j] == 'P') pawn.push_back(i * 8 + j); else if (board[i][j] == 'k') knight = i * 8 + j; // base cases int T[256][8], p = pawn.size(); memset(T, 127, sizeof(T)); queue<state> q; for (int i = 0; i < p; i++) if (cost[knight][pawn[i]] != oo) { int bits = 1 << i; T[bits][i] = cost[knight][pawn[i]]; q.push( { bits, i }); } // DP while (!q.empty()) { state f = q.front(); q.pop(); for (int i = 0; i < p; i++) if (((f.bits >> i) & 1) == 0 && cost[pawn[f.end]][pawn[i]] != oo) { int new_bits = f.bits | (1 << i); if (T[new_bits][i] == oo) { T[new_bits][i] = T[f.bits][f.end] + cost[pawn[f.end]][pawn[i]]; q.push( { new_bits, i }); } else if (T[new_bits][i] > T[f.bits][f.end] + cost[pawn[f.end]][pawn[i]]) T[new_bits][i] = T[f.bits][f.end] + cost[pawn[f.end]][pawn[i]]; } } // output int sol = oo; for (int i = 0; i < p; i++) if (T[(1 << p) - 1][i] < sol) sol = T[(1 << p) - 1][i]; if (sol <= m || p == 0) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
Thursday, December 17, 2015
UVa 11405 - Can U Win?
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment