http://acm.hdu.edu.cn/showproblem.php?pid=4444
题意:给出一个起点一个终点,给出n个矩形的两个对立顶点,问最少需要拐多少次弯可以从起点到达终点,如果不能输出-1.
思路:http://blog.csdn.net/asdfgh0308/article/details/8125832看的是这里的。
因为边界是可以走的,所以不能用点直接来做。
这里用到的就是把一个点拆成一个3*3的方块,中心点就是本身,然后对图进行染色。举个染色的例子:
如果染的是某个颜色的顶点,那么对于那个顶点应当将3*3的方块那样染。
接下来就考虑一种‘L’型拐角的怎么去拐,很多种情况需要去列举。
还有一种就是点的两侧都是被染过的,说明这是一个有两条边界相交的点,因此也是不能走的。
还有注意循环结束的条件不是(SX +SY + EX + EY),因为点可以是负,因这个WA了一个晚上才发现!!!
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define N 1010 4 #define INF 0x3f3f3f3f 5 struct node { 6 int x, y; 7 } p[N][4]; 8 struct P { 9 int x, y, dir; 10 P () {} 11 P (int _x, int _y, int _dir) : x(_x), y(_y), dir(_dir) {}; 12 }; 13 int xx[N], yy[N], x[N], y[N], cx, cy, n, sx, sy, ex, ey; 14 int mp[N][N], dis[N][N][4], dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1}; // 上下右左 15 bool vis[N][N][4]; 16 void Addpoint(int &x, int &y) { 17 x *= 3, y *= 3; 18 cx++; xx[cx] = x; 19 cx++; xx[cx] = x + 1; 20 cx++; xx[cx] = x - 1; 21 cy++; yy[cy] = y; 22 cy++; yy[cy] = y + 1; 23 cy++; yy[cy] = y - 1; 24 } 25 void Find(int &wx, int &wy) { 26 wx = lower_bound(xx + 1, xx + 1 + cx, wx) - xx; 27 wy = lower_bound(yy + 1, yy + 1 + cy, wy) - yy; 28 } 29 void Turn(int x, int y) { 30 if(mp[x-1][y-1] && mp[x+1][y+1] && mp[x+1][y-1] && mp[x-1][y+1]) mp[x][y] = -1; // 四个角都不行 31 else if(mp[x+1][y+1] && mp[x+1][y-1] && mp[x-1][y+1]) mp[x][y] = 1; // 左下角可以 32 else if(mp[x+1][y-1] && mp[x+1][y+1] && mp[x-1][y-1]) mp[x][y] = 2; // 右下角可以 33 else if(mp[x-1][y-1] && mp[x-1][y+1] && mp[x+1][y-1]) mp[x][y] = 3; // 右上角可以 34 else if(mp[x-1][y-1] && mp[x-1][y+1] && mp[x+1][y+1]) mp[x][y] = 4; // 左上角可以 35 else if(mp[x+1][y-1] && mp[x-1][y+1]) mp[x][y] = 5; // 左下角右上角可以 36 else if(mp[x-1][y-1] && mp[x+1][y+1]) mp[x][y] = 6; // 左上角右下角可以 37 if(mp[x-1][y] && mp[x+1][y]) mp[x][y] = -1; 38 if(mp[x][y-1] && mp[x][y+1]) mp[x][y] = -1; 39 } 40 void Build() { 41 memset(mp, 0, sizeof(mp)); 42 for(int i = 1; i <= n; i++) 43 for(int j = p[i][0].x + 1; j <= p[i][1].x - 1; j++) 44 for(int k = p[i][0].y + 1; k <= p[i][3].y - 1; k++) 45 mp[j][k] = -1; 46 for(int i = 1; i <= cx; i++) 47 for(int j = 1; j <= cy; j++) 48 if(!mp[i][j]) Turn(i, j); 49 } 50 bool Check(int x, int y, int nx, int ny, int pdir, int dir) { 51 if(nx < 1 || nx > cx || ny < 1 || ny > cy) return false; 52 if(!mp[x][y]) return true; 53 if(dir == 0) { // 上 54 if(pdir == 2 && (mp[x][y] == 4 || mp[x][y] == 6)) return true; 55 if(pdir == 3 && (mp[x][y] == 3 || mp[x][y] == 5)) return true; 56 } else if(dir == 1) { // 下 57 if(pdir == 2 && (mp[x][y] == 1 || mp[x][y] == 5)) return true; 58 if(pdir == 3 && (mp[x][y] == 2 || mp[x][y] == 6)) return true; 59 } else if(dir == 2) { 60 if(pdir == 0 && (mp[x][y] == 2 || mp[x][y] == 6)) return true; 61 if(pdir == 1 && (mp[x][y] == 3 || mp[x][y] == 5)) return true; 62 } else { 63 if(pdir == 0 && (mp[x][y] == 1 || mp[x][y] == 5)) return true; 64 if(pdir == 1 && (mp[x][y] == 4 || mp[x][y] == 6)) return true; 65 } 66 return false; 67 } 68 69 int BFS() { 70 memset(vis, 0, sizeof(vis)); 71 memset(dis, INF, sizeof(dis)); 72 queue<P> que; while(!que.empty()) que.pop(); 73 for(int i = 0; i < 4; i++) { 74 que.push(P(sx, sy, i)), dis[sx][sy][i] = 0, vis[sx][sy][i] = 1; 75 } 76 int ans = INF; 77 while(!que.empty()) { 78 P now = que.front(); que.pop(); 79 int x = now.x, y = now.y, dir = now.dir; 80 if(x == ex && y == ey) ans = min(ans, dis[x][y][dir]); 81 vis[x][y][dir] = 0; 82 for(int k = 0; k < 4; k++) { 83 int nx = now.x + dx[k], ny = now.y + dy[k], ndir = k; 84 if(!Check(x, y, nx, ny, dir, ndir)) continue; 85 int w = ndir == dir ? 0 : 1; w += dis[x][y][dir]; 86 if(w < dis[nx][ny][ndir]) { 87 dis[nx][ny][ndir] = w; 88 if(!vis[nx][ny][ndir]) vis[nx][ny][ndir] = 1, que.push(P(nx, ny, ndir)); 89 } 90 } 91 } 92 if(ans == INF) puts("-1"); 93 else printf("%d ", ans); 94 // puts(""); 95 } 96 int main() { 97 while(scanf("%d%d%d%d", &sx, &sy, &ex, &ey)) { // sx + sy + ex + ey == 0 98 if(!sx && !sy && !ex && !ey) break; 99 scanf("%d", &n); cx = cy = 0; 100 for(int i = 1; i <= n; i++) { 101 int x1, x2, y1, y2; 102 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 103 Addpoint(x1, y1); Addpoint(x2, y2); 104 if(x1 > x2) swap(x1, x2); 105 if(y1 > y2) swap(y1, y2); 106 p[i][0] = (node) { x1, y1 }; 107 p[i][1] = (node) { x2, y1 }; 108 p[i][2] = (node) { x2, y2 }; 109 p[i][3] = (node) { x1, y2 }; 110 } 111 Addpoint(sx, sy); Addpoint(ex, ey); 112 int tx = cx, ty = cy; 113 sort(xx + 1, xx + 1 + cx); cx = unique(xx + 1, xx + 1 + cx) - xx - 1; 114 sort(yy + 1, yy + 1 + cy); cy = unique(yy + 1, yy + 1 + cy) - yy - 1; 115 for(int i = 1; i <= n; i++) 116 for(int j = 0; j < 4; j++) 117 Find(p[i][j].x, p[i][j].y); 118 Find(sx, sy); Find(ex, ey); 119 Build(); 120 BFS(); 121 } 122 return 0; 123 }