Loading

HDU 4444:Walk(思维建图+BFS)***

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\n", 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 }

 

posted @ 2017-05-11 02:15  Shadowdsp  阅读(274)  评论(0编辑  收藏  举报