• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            糯米

            TI DaVinci, gstreamer, ffmpeg
            隨筆 - 167, 文章 - 0, 評論 - 47, 引用 - 0
            數據加載中……

            POJ 1475 Pushing Boxes 推箱子游戲 寬搜

            思路:
            這題就是平常玩的那種推箱子的游戲。不過簡化了一下,只是推一個箱子而已。
            用 bfs 來做,搜索樹里面的節點,也就是狀態,可以定義為:
            1. 箱子的坐標
            2. 上一次推完之后,人要走多少步才能到達箱子的上、下、左、右側。如果到達不了,值則為無窮大。

            這樣,狀態轉移的時候。
            就首先看是否能向某個方向推。如果能的話,就推一下。
            然后對人進行一次 bfs ,看下此時到達箱子的各個側要走多少步。
            就可以生成一個新的狀態了。

            判重的處理做得很簡單:
            對于同一個坐標,不可能存在一個狀態,它的“人要走多少步才能到達箱子的上、下、左、右側”這四個值都比另外一個狀態大。

            代碼寫得很亂,調試得真痛苦,足足4K多啊,看了下 status 里面,發現有的牛人代碼還是寫得很短的,佩服佩服!
            后來又看了標程,發現太飄逸了,看不懂。。



            #include <stdio.h>
            #include 
            <stdlib.h>
            #include 
            <string.h>

            #define DATA_SIZE 24
            #define QUEUE_SIZE 65536
            #define INFINITE 1000000

            #define dbp printf

            struct node {
                
            int y, x, dir, dis[4], pushes, walks;
                
            struct node *next, *hash_next;
            }
            ;

            struct queue {
                
            struct node arr[QUEUE_SIZE];
                
            int qh, qt;
            }
            ;

            struct node box, man, off[4= {
                
            {-10}{10}{0-1}{01}    
            }
            ;
            int H, W;
            char map[DATA_SIZE][DATA_SIZE];
            char lower[] = "nswe", upper[] = "NSWE";

            __inline 
            int input()
            {
                
            int i, j;

                scanf(
            "%d%d"&H, &W);
                
            if (!H)
                    
            return 0;

                
            for (i = 0; i < H; i++{
                    scanf(
            "%s", map[i]);
                    
            for (j = 0; j < W; j++{
                        
            if (map[i][j] == 'B'{
                            box.x 
            = j;
                            box.y 
            = i;
                            map[i][j] 
            = '.';
                        }
             else if (map[i][j] == 'S'{
                            man.x 
            = j;
                            man.y 
            = i;
                            map[i][j] 
            = '.';
                        }

                    }

                }


                
            return 1;
            }


            __inline 
            int can_go(int y, int x)
            {
                
            return x >= 0 && x < W && y >= 0 && y < H && map[y][x] != '#';
            }


            __inline 
            void move_man(struct node *b, struct node *m, struct node *rec[])
            {
                
            int mask, got, i;
                
            static struct queue q;
                
            static char visited[DATA_SIZE][DATA_SIZE];

                mask 
            = 0;
                
            for (i = 0; i < 4; i++)
                    
            if (can_go(b->+ off[i].y, b->+ off[i].x)) 
                        mask 
            |= 1 << i;

            #define PUSH(_y, _x, _walks, _next, _dir)    \
                
            if (_y == b->&& _x == b->x) {    \
                    got 
            |= 1 << _dir;    \
                    b
            ->dis[_dir] = _walks;    \
                    
            if (rec)    \
                        rec[_dir] 
            = m;    \
                }
             else if (!visited[_y][_x]) {    \
                    q.arr[q.qt].y 
            = _y;    \
                    q.arr[q.qt].x 
            = _x;    \
                    q.arr[q.qt].walks 
            = _walks;    \
                    q.arr[q.qt].next 
            = _next;    \
                    q.arr[q.qt].dir 
            = _dir;    \
                    visited[_y][_x] 
            = 1;    \
                    q.qt
            ++;    \
                }


                q.qh 
            = q.qt = 0;
                
            for (i = 0; i < 4; i++)
                    b
            ->dis[i] = INFINITE;
                memset(visited, 
            0sizeof(visited));
                PUSH(m
            ->y, m->x, 0, NULL, 0);
                got 
            = 0;

                
            while (q.qh != q.qt && got != mask) {
                    m 
            = &q.arr[q.qh++];
                    
            for (i = 0; i < 4; i++{
                        
            if (!can_go(m->+ off[i].y, m->+ off[i].x))
                            
            continue;
                        PUSH(m
            ->+ off[i].y, m->+ off[i].x, 
                             m
            ->walks + 1, m, i
                             );
                    }

                }


            #undef PUSH

            }


            __inline 
            struct node *reverse(struct node *t)
            {
                
            struct node *p, *n;

                p 
            = NULL;
                
            while (t) {
                    n 
            = t->next;
                    t
            ->next = p;
                    p 
            = t;
                    t 
            = n;
                }


                
            return p;
            }


            __inline 
            int hash_insert(struct node **p, struct node *b)
            {
                
            int i;
                
            struct node *h;

                
            for (h = *p; h; h = h->hash_next) {
                    
            for (i = 0; i < 4; i++)
                        
            if (h->dis[i] > b->dis[i])
                            
            break;
                    
            if (i == 4)
                        
            return 0;
                }

                b
            ->hash_next = *p;
                
            *= b;
                
            return 1;
            }


            __inline 
            void dump_walks(struct node *b, struct node *m, int d)
            {
                
            struct node *rec[4];

                move_man(b, m, rec);
                
            //dbp("(%d,%d) -> (%d,%d) %c\n", m->x, m->y, b->x, b->y, lower[d]);
                for (b = reverse(rec[d])->next; b; b = b->next)
                    putchar(lower[b
            ->dir]);
                putchar(upper[d]);
            }


            __inline 
            void solve()
            {
                
            struct node *b, *n, *best;
                
            static struct queue q;
                
            static struct node *hash[DATA_SIZE][DATA_SIZE];
                
            int i;

                memset(hash, 
            0sizeof(hash));

            #define PUSH(_y, _x, _m, _pushes, _walks, _next, _dir)    \
            {    \
                n 
            = &q.arr[q.qt];    \
                n
            ->= _y;    \
                n
            ->= _x;    \
                n
            ->pushes = _pushes;    \
                n
            ->walks = _walks;    \
                n
            ->next = _next;    \
                n
            ->dir = _dir;    \
                move_man(n, _m, NULL);    \
                
            if (map[_y][_x] == 'T'{    \
                    
            if (!best || n->walks < best->walks) {    \
                        best 
            = n;    \
                        q.qt
            ++;    \
                    }
                \
                }
             else if (hash_insert(&hash[_y][_x], n)) {    \
                    q.qt
            ++;    \
                }
                \
            }


                best 
            = NULL;
                q.qh 
            = q.qt = 0;
                PUSH(box.y, box.x, 
            &man, 00, NULL, 0);

                
            while (q.qt != q.qh) {
                    b 
            = &q.arr[q.qh++];
                    
            if (best && b->pushes > best->pushes)
                        
            break;
                    
            for (i = 0; i < 4; i++{
                        
            if (!can_go(b->+ off[i].y, b->+ off[i].x))
                            
            continue;
                        
            if (b->dis[i] == INFINITE)
                            
            continue;
                        PUSH(b
            ->+ off[i].y, b->+ off[i].x, 
                             b, b
            ->pushes + 1, b->dis[i] + b->walks,
                             b, i
                             );
                    }

                }


                
            if (!best) {
                    printf(
            "Impossible.\n\n");
                    
            return ;
                }


                
            //dbp("%d pushes %d walks\n", best->pushes, best->walks);
                b = reverse(best);
                dump_walks(b, 
            &man, b->next->dir);
                n 
            = b;
                
            for (b = b->next; b->next; b = b->next) {
                    dump_walks(b, n, b
            ->next->dir);
                    n 
            = b;
                }

                printf(
            "\n\n");
            }


            int main()
            {
                
            int i;
                
                freopen(
            "e:\\test\\in.txt""r", stdin);

                
            for (i = 1; input(); i++{
                    printf(
            "Maze #%d\n", i);
                    solve();
                }


                
            return 0;
            }

            posted on 2010-03-30 09:07 糯米 閱讀(775) 評論(0)  編輯 收藏 引用 所屬分類: POJ

            亚洲色欲久久久久综合网| 久久成人小视频| 精品久久综合1区2区3区激情| 91亚洲国产成人久久精品网址| 91精品国产综合久久香蕉 | 精品久久777| 久久久久国产亚洲AV麻豆| 伊人久久大香线焦AV综合影院| 国产精品一区二区久久国产| 久久国产精品波多野结衣AV| 中文无码久久精品| 国产成人久久精品二区三区| 久久伊人精品一区二区三区 | 性做久久久久久久| 国产精品热久久毛片| 亚洲中文字幕久久精品无码APP | 久久久av波多野一区二区| 久久国产精品无码网站| 无码人妻精品一区二区三区久久久| 国产成人久久精品二区三区| 亚洲精品乱码久久久久久按摩 | 久久国产色av免费看| 亚洲国产精品久久| 97久久国产露脸精品国产| 国产亚洲精午夜久久久久久| 久久综合亚洲欧美成人| 久久久久久久亚洲精品| 潮喷大喷水系列无码久久精品| 亚洲欧美一区二区三区久久| 99热热久久这里只有精品68| 久久精品国产清高在天天线| 亚洲日本va午夜中文字幕久久 | 精品久久久噜噜噜久久久| 久久这里的只有是精品23| 国产福利电影一区二区三区,免费久久久久久久精 | 久久中文娱乐网| 色诱久久久久综合网ywww| 中文字幕无码久久人妻| 久久精品成人免费国产片小草| 99久久精品国产免看国产一区| 日本欧美久久久久免费播放网 |