/* 对于双广一直很害怕,一直不敢去写。。。 对于状态的保存总是感觉很陌生,可是BFS DFS 中的状态很重要,好好学状态 以前就想写这个题目。。。 终于AC了。。 */ #include <iostream> #include <cstdio> #include <bitset> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N =( (1 << 24) + 10); bitset<N> hash1; // 说这个能节省内存 bitset<N> hash2; int dir1[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} }; int dir2[4][2] = { {-2, 0}, {2, 0}, {0, 2}, {0, -2} }; char map1[9][9], map2[9][9]; struct Dir { int x, y; }; struct Node { Dir dir[4]; int step; char map[9][9]; Node() { for(int i = 0; i < 9; i++) for(int j = 0; j < 9; j++) map[i][j] = 'A'; step = 0; } }; Node start, end; inline bool cmp(const Dir &a, const Dir&b) {//对坐标排序避免不必要的入队列 if(a.x == b.x) return a.y < b.y; else return a.x < b.x; } inline int Hash(const Node &node) {//将坐标转化为一维的 int num; int sum = 0; for(int i = 0; i < 4; i++) { num = (node.dir[i].x - 1) * 8 + node.dir[i].y; sum = 64 * sum + num ; } return sum; } void BFS() { queue<Node> Q1, Q2; Q1.push(start); Q2.push(end); Node now, next; hash1.reset(); hash2.reset(); hash1[ Hash(start)] = true; hash2[ Hash(end)] = true; int x, y; for(int step = 0; step < 4; step++) { while(!Q1.empty()) { next = now = Q1.front(); Q1.pop(); if(next.step > 4) break; for(int i = 0; i < 4; i++) // 四个点 D表示棋子,A表示空白 { for(int j = 0; j < 4; j++) {// 先搜一步的方向 next = now; x = now.dir[i].x + dir1[j][0]; y = now.dir[i].y + dir1[j][1]; if(x >= 1 && x <= 8 && y >= 1 && y <= 8 && now.map[x][y] != 'D') { next.dir[i].x = x; next.dir[i].y = y; next.step = now.step + 1; next.map[x][y] = 'D'; next.map[now.dir[i].x][now.dir[i].y] = 'A'; sort(next.dir, next.dir + 4 , cmp); if(hash1[ Hash(next) ]) continue; if(hash2[ Hash(next) ] ) {//如果该状态在end 搜过来hash过的就说明存在 printf("YES/n"); return ; } hash1[ Hash(next) ] = true; Q1.push(next); } } for(int j = 0; j < 4; j++) { next = now; x = now.dir[i].x + dir2[j][0]; y = now.dir[i].y + dir2[j][1]; if(x >= 1 && x <= 8 && y >= 1 && y <= 8 && now.map[now.dir[i].x + dir1[i][0] ][now.dir[i].y + dir1[i][1] ] == 'D' && now.map[x][y] != 'D') { next.dir[i].x = x; next.dir[i].y = y; next.step = now.step + 1; next.map[x][y] = 'D'; next.map[now.dir[i].x][now.dir[i].y] = 'A'; sort(next.dir, next.dir + 4 , cmp); if(hash1[ Hash(next) ]) continue; if(hash2[ Hash(next) ] ) { printf("YES/n"); return ; } hash1[ Hash(next) ] = true; Q1.push(next); } } } } while(!Q2.empty()) { next = now = Q2.front(); Q2.pop(); if(next.step == step + 1) break; for(int i = 0; i < 4; i++) // 四个点 D表示棋子,A表示空白 { for(int j = 0; j < 4; j++) { next = now; x = now.dir[i].x + dir1[j][0]; y = now.dir[i].y + dir1[j][1]; if(x >= 1 && x <= 8 && y >= 1 && y <= 8 && now.map[x][y] != 'D') { next.dir[i].x = x; next.dir[i].y = y; next.step = now.step + 1; next.map[x][y] = 'D'; next.map[now.dir[i].x][now.dir[i].y] = 'A'; sort(next.dir, next.dir + 4 , cmp); if(hash2[ Hash(next)]) continue; if(hash1[ Hash(next) ] ) { printf("YES/n"); return ; } hash2[ Hash(next) ] = true; Q2.push(next); } } for(int j = 0; j < 4; j++) { next = now; x = now.dir[i].x + dir2[j][0]; y = now.dir[i].y + dir2[j][1]; if(x >= 1 && x <= 8 && y >= 1 && y <= 8 && now.map[now.dir[i].x + dir1[i][0] ][now.dir[i].y + dir1[i][1] ] == 'D' && now.map[x][y] != 'D') { next.dir[i].x = x; next.dir[i].y = y; next.step = now.step + 1; next.map[x][y] = 'D'; next.map[now.dir[i].x ][now.dir[i].y ] = 'A'; sort(next.dir, next.dir + 4 , cmp); if(hash2[ Hash(next)]) continue; if(hash1[ Hash(next) ] ) { printf("YES/n"); return ; } hash2[ Hash(next) ] = true; Q2.push(next); } } } } } printf("NO/n"); return ; } int main() { int x, y; while(scanf("%d %d", &x, &y) != EOF) { Node ss, ee; ss.map[x][y] = 'D'; ss.dir[0].x = x; ss.dir[0].y = y; for(int i = 1; i < 4; i++) { scanf("%d %d", &x, &y); ss.map[x][y] = 'D'; ss.dir[i].x = x; ss.dir[i].y = y; } for(int i = 0; i < 4; i++) { scanf("%d %d", &x, &y); ee.map[x][y] = 'D'; ee.dir[i].x = x; ee.dir[i].y = y; } start = ss; end = ee; sort(start.dir, start.dir + 4 , cmp); sort(end.dir, end.dir + 4, cmp); BFS(); } return 0; }