zoukankan      html  css  js  c++  java
  • 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
    ", 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 }
  • 相关阅读:
    MongoDB小结07
    MongoDB小结07
    MongoDB小结06
    MongoDB小结05
    MongoDB小结04
    MongoDB小结03
    MongoDB小结02
    MongoDB小结01
    this与super
    UVa 11174
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6839046.html
Copyright © 2011-2022 走看看