• POJ 搜索(3)


    搜索

    较麻烦的搜索题目训练

    poj1069,poj3322,poj1475,poj1924,poj2049,poj3426

    广搜的状态优化

    poj1768,poj1184,poj1872,poj1324,poj2046,poj1482

    深搜的优化

    poj3131,poj2870,poj2286

    较麻烦的搜索题目训练 

    poj 3322

    感觉这题应该归类到模拟题。。。bfs&&priority_queue直接模拟就行。昨晚写了一个版本,因为状态记录的太多了,MLE一次。发现总共有三种形状,每种形状可以用一个坐标加一个标号表示。比如约定立着的用(x, y, 0)表示,横着的为(x, y), (x, y + 1)用(x, y, 1)表示,竖着的为(x, y),(x + 1, y)用(x, y, 2)表示。然后直接模拟出每种形状可以转移到的形状,bfs。

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    //#include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const int inf = ~0u>>2;
    
    using namespace std;
    
    const int maxn = 550;
    
    struct Point {
        int x, y;
        int f;
        Point() {}
        Point(int a, int b, int f) : x(a), y(b), f(f) {}
        bool operator == (const Point p) const {
            return (x == p.x && y == p.y && f == p.f);
        }
    };
    
    struct node {
        Point now;
        int dis;
        node() {}
        node(Point a, int b) : now(a), dis(b) {}
        bool operator < (const node& cmp) const {
            return dis > cmp.dis;
        }
    };
    
    char mp[maxn][maxn];
    bool vis[maxn][maxn][3];
    int R, C;
    Point s1, s2, tg;
    
    bool inmap(int x, int y) {
        if(x < 0 || x >= R || y < 0 || y >= C)  return false;
        return true;
    }
    
    bool check(int x, int y) {
        if(inmap(x, y) && mp[x][y] != '#')  return true;
        return false;
    }
    
    priority_queue<node> q;
    
    int bfs() {
        while(!q.empty())   q.pop();
        CL(vis, false);
    
        q.push(node(s1, 0));
        vis[s1.x][s1.y][s1.f] = true;
    
        node u;
        int x, y;
        while(!q.empty()) {
            u = q.top(); q.pop();
            //printf("%d %d %d %d\n", u.now.x, u.now.y, u.now.f, u.dis);
            if(u.now == tg) {
                return u.dis;
            }
            x = u.now.x; y = u.now.y;
            if(u.now.f == 0) {
                //u
                if(check(x-2, y) && check(x-1, y) && !vis[x-2][y][2]) {
                    vis[x-2][y][2] = true;
                    q.push(node(Point(x-2, y, 2), u.dis + 1));
                }
                //d
                if(check(x+1, y) && check(x+2, y) && !vis[x+1][y][2]) {
                    vis[x+1][y][2] = true;
                    q.push(node(Point(x+1, y, 2), u.dis + 1));
                }
                //l
                if(check(x, y-2) && check(x, y-1) && !vis[x][y-2][1]) {
                    vis[x][y-2][1] = true;
                    q.push(node(Point(x, y-2, 1), u.dis + 1));
                }
                //r
                if(check(x, y+1) && check(x, y+2) && !vis[x][y+1][1]) {
                    vis[x][y+1][1] = true;
                    q.push(node(Point(x, y+1, 1), u.dis + 1));
                }
            } else if(u.now.f == 1) {
                //u
                if(check(x-1, y) && check(x-1,y+1) && !vis[x-1][y][1]) {
                    vis[x-1][y][1] = true;
                    q.push(node(Point(x-1,y,1), u.dis + 1));
                }
                //d
                if(check(x+1,y) && check(x+1,y+1) && !vis[x+1][y][1]) {
                    vis[x+1][y][1] = true;
                    q.push(node(Point(x + 1, y, 1), u.dis + 1));
                }
                //l
                if(check(x,y-1) && !vis[x][y-1][0] && mp[x][y-1] != 'E') {
                    vis[x][y-1][0] = true;
                    q.push(node(Point(x, y-1, 0), u.dis + 1));
                }
                //r
                if(check(x, y+2) && !vis[x][y+2][0] && mp[x][y+2] != 'E') {
                    vis[x][y+2][0] = true;
                    q.push(node(Point(x, y + 2, 0), u.dis + 1));
                }
            } else {
                //u
                if(check(x-1, y) && !vis[x-1][y][0] && mp[x-1][y] != 'E') {
                    vis[x-1][y][0] = true;
                    q.push(node(Point(x-1, y, 0), u.dis + 1));
                }
                //d
                if(check(x + 2, y) && !vis[x + 2][y][0] && mp[x+2][y] != 'E') {
                    vis[x + 2][y][0] = true;
                    q.push(node(Point(x+2, y, 0), u.dis + 1));
                }
                //l
                if(check(x, y - 1) && check(x + 1, y - 1) && !vis[x][y - 1][2]) {
                    vis[x][y - 1][2] = true;
                    q.push(node(Point(x, y - 1, 2), u.dis + 1));
                }
                //r
                if(check(x, y + 1) && check(x + 1, y + 1) && !vis[x][y + 1][2]) {
                    vis[x][y+1][2] = true;
                    q.push(node(Point(x, y + 1, 2), u.dis + 1));
                }
            }
        }
        return -1;
    }
    
    int main() {
        Read();
    
        int i, j;
        while(~scanf("%d%d", &R, &C)) {
            if(R + C == 0)  break;
            s1 = Point(-1, -1, -1);
            s2 = Point(-1, -1, -1);
    
            for(i = 0; i < R; ++i) {
                scanf("%s", mp[i]);
                for(j = 0; j < C; ++j) {
                    if(mp[i][j] == 'X') {
                        if(s1.x == -1)  s1 = Point(i, j, -1);
                        else    s2 = Point(i, j, -1);
                    }
                    if(mp[i][j] == 'O') {
                        tg = Point(i, j, 0);
                    }
                }
            }
            if(s2.x != -1) {
                if(s1.x == s2.x) {
                    s1.y = min(s1.y, s2.y);
                    s1.f = 1;
                } else {
                    s1.x = min(s1.x, s2.x);
                    s1.f = 2;
                }
            } else {
                s1.f = 0;
            }
            int ans = bfs();
            if(ans == -1)   puts("Impossible");
            else    printf("%d\n", ans);
        }
        return 0;
    }

    广搜的状态优化

    POJ 1184

    这题过的好揪心,这两天忙着复习,3天才过掉。。。

    开始直接暴力bfs,然后果断MLE掉,优化一下内存有TLE掉 。后来看题解,有这个ppthttp://wenku.baidu.com/view/0c2742fb770bf78a65295406.html

    还有这个解题报告:http://hi.baidu.com/kmzchchycfdeovr/item/6d7358b32be4edf762388eb6

    注意,这个解题报告是错误的,不能忽略左移的情况。不如这个数据:000159 000519

    思路是对于移动操作和数值变换操作分开处理。

    先预处理出移动操作到达某个状态时用到的最小次数。至于这个状态,因为有六个位置,所以可以设定为num[0...5]记录当前和六个位置顺序状态,num[6]记录这六个位置被访问过的状态,num[7]记录到达这个状态的最小步数。被访问过的位置的状态有:

    int Psta[10][6] = {
        {1, 0, 0, 0, 0, 0},//0
        {1, 1, 0, 0, 0, 0},//1
        {1, 1, 1, 0, 0, 0},//2
        {1, 1, 1, 1, 0, 0},//3
        {1, 1, 1, 1, 1, 0},//4
        {1, 0, 0, 0, 0, 1},//5
        {1, 1, 0, 0, 0, 1},//6
        {1, 1, 1, 0, 0, 1},//7
        {1, 1, 1, 1, 0, 1},//8
        {1, 1, 1, 1, 1, 1} //9
    };

    bfs时记录当前六个位置的顺序状态,当前光标的位置,当前被访问过的位置状态(Psta),还有当前用掉的步数。

    这个预处理出来每种六个位置顺序状态所用的步数。然后与目标数字进行对比,需要增加或者减少的直接累加上就可以。。。

    ps:debug了好久,因为某傻冒错误。。。T_T

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = ~0u>>2;
    
    using namespace std;
    
    struct node {
        int a[6];
        int pos, sta, stp;
    };
    
    queue<node> q;
    
    int Psta[10][6] = {
        {1, 0, 0, 0, 0, 0},//0
        {1, 1, 0, 0, 0, 0},//1
        {1, 1, 1, 0, 0, 0},//2
        {1, 1, 1, 1, 0, 0},//3
        {1, 1, 1, 1, 1, 0},//4
        {1, 0, 0, 0, 0, 1},//5
        {1, 1, 0, 0, 0, 1},//6
        {1, 1, 1, 0, 0, 1},//7
        {1, 1, 1, 1, 0, 1},//8
        {1, 1, 1, 1, 1, 1} //9
    };
    
    bool vis[10][6][6][6][6][6][6][6];
    int num[50000][8], t;
    
    void bfs() {
        while(!q.empty())   q.pop();
        CL(vis, false);
        CL(num, 0);
        t = 0;
    
        node u, v;
        int i;
        u.pos = 0;
        u.sta = 0;
        u.stp = 0;
        for(i = 0; i < 6; ++i)  u.a[i] = i;
        q.push(u);
        vis[0][0][0][1][2][3][4][5] = true;
        while(!q.empty()) {
            u = q.front(); q.pop();
            for(i = 0; i < 6; ++i) {
                num[t][i] = u.a[i];
            }
            num[t][6] = u.sta;
            num[t++][7] = u.stp;
            v = u;
            ++v.stp;
            if(v.pos > 0) {
                swap(v.a[0], v.a[v.pos]);
                if(!vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]]) {
                    vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]] = true;
                    q.push(v);
                }
                swap(v.a[0], v.a[v.pos]);
                --v.pos;
                if(!vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]]) {
                    vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]] = true;
                    q.push(v);
                }
                ++v.pos;
            }
            if(v.pos < 5) {
                ++v.pos;
                if(v.pos > v.sta || (v.sta > 4 && v.pos > v.sta - 5)) {
                    if(v.sta == 4 || v.sta == 9)  v.sta = 9;
                    else    ++v.sta;
                }
                if(!vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]]) {
                    vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]] = true;
                    q.push(v);
                }
                v = u; ++v.stp;
                swap(v.a[5], v.a[v.pos]);
                if(v.sta <= 4)  v.sta += 5;
                if(!vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]]) {
                    vis[v.sta][v.pos][v.a[0]][v.a[1]][v.a[2]][v.a[3]][v.a[4]][v.a[5]] = true;
                    q.push(v);
                }
            }
        }
    }
    
    int a[6], b[6];
    
    int main() {
        //freopen("data.in", "r", stdin);
        //freopen("data1.out", "w", stdout);
        bfs();
        int st, ed, i, j;
        while(~scanf("%d%d", &st, &ed)) {
            for(i = 5; i >= 0; --i) {
                a[i] = st%10;
                st /= 10;
            }
            for(i = 5; i >= 0; --i) {
                b[i] = ed%10;
                ed /= 10;
            }
            int ans = inf, stp, p;
            for(i = 0; i < t; ++i) {
                stp = num[i][7];
                /*if(num[i][6] == 9) {
                    for(j = 0; j < 6; ++j) {
                        printf("%d", num[i][j]);
                    }
                    printf(" %d %d\n", num[i][6], num[i][7]);
                }*/
                /*
                for(j = 0; j < 6; ++j) {
                    printf("%d", num[i][j]);
                }
                printf(" %d %d\n", num[i][6], num[i][7]);
                */
                for(j = 0; j < 6; ++j) {
                    if(a[num[i][j]] != b[j] && !Psta[num[i][6]][j])    break;
                    else    stp += abs(a[num[i][j]] - b[j]);
                }
                if(j == 6 && stp < ans)  {ans = stp; p = i;}
            }
            /*
            puts("**************");
            for(j = 0; j < 6; ++j)  printf("%d", a[num[p][j]]);
            puts("\n***************");
            */
            printf("%d\n", ans);
        }
        return 0;
    }

    POJ 1324   

     话说做完这题真想写个贪吃蛇游戏。 

    因为蛇的身子很小,只有八个坐标,可以只记录蛇头的位置,然后记录每一个与前一个位置的相对位置关系。只有上下左右,用0, 1, 2, 3表示,这样就可以化成4进制的状态压缩了。直接bfs,注意蛇头走的下一个位置不能碰到蛇身上

    时间耗时很大, 写的很烂。。。不知道用A*怎么写。。。

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    //#include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const int inf = ~0u>>2;
    
    using namespace std;
    
    struct snake {
        int x, y;
        int sta;
        int dis;
        snake() {}
        snake(int a, int b, int c, int d) :
            x(a), y(b), sta(c), dis(d) {}
    };
    
    snake st;
    queue<snake> q;
    bool vis[21][21][16390];
    bool mp[21][21];
    int n, m, l;
    int body[9][2];
    int ssta[9];
    
    int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1},};
    
    void get_ssta(int sta) {
        for(int i = 0; i < l-1; ++i) {
            ssta[i] = sta%4;
            sta /= 4;
        }
    }
    
    void get_body(snake u) {
        body[l-1][0] = u.x; body[l-1][1] = u.y;
        get_ssta(u.sta);
    
        for(int i = l - 2; i >= 0; --i) {
            body[i][0] = body[i+1][0] + dir[ssta[i]][0];
            body[i][1] = body[i+1][1] + dir[ssta[i]][1];
        }
    }
    
    bool inmap(int x, int y) {
        if(x <= 0 || x > n || y <= 0 || y > m)  return false;
        return true;
    }
    
    bool check(int x, int y) {
    
        if(mp[x][y] == true || !inmap(x, y)) return false;
    
        for(int i = 0; i < l; ++i) {
            if(x == body[i][0] && y == body[i][1])  return false;
        }
        return true;
    }
    
    int pos(int a, int b, int x, int y) {
        x -= a; y -= b;
        for(int i = 0; i < 4; ++i) {
            if(x == dir[i][0] && y == dir[i][1])    return i;
        }
        return -1;
    }
    
    int bfs() {
        while(!q.empty())   q.pop();
        q.push(st);
        snake u;
        CL(vis, false);
        vis[st.x][st.y][st.sta] = true;
        int x, y, i, j, nsta, a, b;
    
        while(!q.empty()) {
            u = q.front(); q.pop();
            if(u.x == 1 && u.y == 1)    return u.dis;
            get_body(u);
            for(j = 0; j < 4; ++j) {
                x = u.x + dir[j][0];
                y = u.y + dir[j][1];
                if(!check(x, y))    continue;
                nsta = 0;
                a = x; b = y;
                for(i = l - 1; i >= 1; --i) {
                    nsta = nsta*4 + pos(a, b, body[i][0], body[i][1]);
                    a = body[i][0]; b = body[i][1];
                }
                if(!vis[x][y][nsta]) {
                    vis[x][y][nsta] = true;
                    q.push(snake(x, y, nsta, u.dis + 1));
                }
            }
        }
        return -1;
    }
    
    int main() {
        //Read();
    
        int i, k, a, b, x, y, cas = 0;
        while(~scanf("%d%d%d", &n, &m, &l)) {
            if(n + m + l == 0)  break;
            CL(vis, false);
            scanf("%d%d", &a, &b);
            st.x = a; st.y = b;
            st.sta = st.dis = 0;
            for(i = 1; i < l; ++i) {
                scanf("%d%d", &x, &y);
                st.sta = st.sta*4 + pos(a, b, x, y);
                a = x; b = y;
            }
            scanf("%d", &k);
            CL(mp, false);
            while(k--) {
                scanf("%d%d", &a, &b);
                mp[a][b] = true;
            }
            printf("Case %d: %d\n", ++cas, bfs());
        }
        return 0;
    }

      

  • 相关阅读:
    elementui form 相关表单验证
    函数注释备注
    elementui elform 某一值为数组,各项必填验证
    selenium等待的三种方式(详细)
    什么是python
    pytest基础
    pymysql数据库操作
    自动化测试1
    allure生成测试报告
    python读取excel的文件
  • 原文地址:https://www.cnblogs.com/vongang/p/2789651.html
Copyright © 2020-2023  润新知