POJ 1324 Holedox Moving 贪食蛇

POJ 1324 Holedox Moving 贪食蛇

思路:

继推箱子以后,又发现POJ上有这类题目,哈哈。
这次是给出一条贪食蛇当前的状态、墙的位置、食物的位置。求吃到食物需要走的最小的步数。

这类题目是相当牛逼的!高手的速度可以做到很BT的。
在 status 上面就看到有 0ms 的!相当震惊,如此庞大的数据量能做到 0ms,肯定是神牛!
后来搜了一下,还找到了那位神牛的博客,看了一下,发现看不大懂,杯具。。

哪一天有空,一定会再想一下这道题的。

一开始想了一个剪枝的方法,如果:
1. 蛇头在可以穿越蛇的身体的情况下,到达食物所用的最小步数,
2. 蛇头在不能穿越身体的情况下,到达食物所用的最小步数
这两个值相等的话,就不用继续扩展当前状态了。
一开始觉得还挺牛逼,结果一提交 TLE了,无语了。POJ 的数据真不是盖的,当然主要问题还是哥的代码太烂了。

 后来改成现在这样子了。跑了1秒+。。
表示蛇的状态的时候,保存头的位置、每段身体跟前一段偏移的方向。
不然没法判重的。

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

#define  QUEUE_SIZE (1 << 16)

struct  node  {
    
char y, x;
    unsigned 
short s;
    
int step;
}
;

int  N, M, L;
int  hash[ 24 ][ 24 ][ 1   <<   14 ], tm;
struct  node queue[QUEUE_SIZE];
int  head, tail;
char  map[ 24 ][ 24 ];
unsigned 
short  mask;

inline 
struct  node input()
{
    
struct node t;
    
int y, x, i, nx, ny;

    scanf(
"%d%d"&y, &x);
    t.y 
= y;
    t.x 
= x;
    t.s 
= 0;
    
for (i = 0; i < L - 1; i++{
        scanf(
"%d%d"&ny, &nx);
        
if (nx == x) 
            t.s 
|= (ny < y ? 0 : 1<< (i * 2);
        
else
            t.s 
|= (nx < x ? 2 : 3<< (i * 2);
        y 
= ny;
        x 
= nx;
    }

    t.step 
= 0;

    
return t;
}


inline 
void  push( struct  node t)
{
    
if (hash[t.y][t.x][t.s] == tm)
        
return ;
    
    hash[t.y][t.x][t.s] 
= tm;
    queue[tail
++= t;
    tail 
&= QUEUE_SIZE - 1;
}


inline 
void  move( struct  node t,  int  dir)
{
    
int i, y, x;
    
    y 
= t.y;
    x 
= t.x;

    
switch (dir) {
    
case 0: t.y--; dir = 1break;
    
case 1: t.y++; dir = 0break;
    
case 2: t.x--; dir = 3break;
    
case 3: t.x++; dir = 2break;
    }

    
if (t.y < 1 || t.y > N || t.x < 1 || t.x > M || map[t.y][t.x] == '@')
        
return ;

    
for (i = 0; i < L - 1; i++{
        
switch ((t.s >> (i * 2)) & 3{
        
case 0: y--break;
        
case 1: y++break;
        
case 2: x--break;
        
case 3: x++break;
        }

        
if (t.y == y && t.x == x)
            
break;
    }

    
if (i < L - 1)
        
return ;

    t.s 
<<= 2;
    t.s 
&= mask;
    t.s 
|= dir;
    t.step
++;

    push(t);
}


inline 
int  bfs( struct  node t)
{
    head 
= tail = 0;
    tm
++;
    push(t);
    
while (head != tail) {
        t 
= queue[head++];
        head 
&= QUEUE_SIZE - 1;
        
if (t.x == 1 && t.y == 1)
            
break;
        move(t, 
0);
        move(t, 
1);
        move(t, 
2);
        move(t, 
3);
    }


    
return (t.x == 1 && t.y == 1? t.step : -1;
}


int  main()
{
    
int y, x, c, k;
    
struct node t;
 
    freopen(
"e:\\test\\in.txt""r", stdin);

    
for (c = 1; scanf("%d%d"&N, &M), N; c++{
        memset(map, 
'.'sizeof(map));
        scanf(
"%d"&L);
        mask 
= (1 << ((L - 1* 2)) - 1;
        t 
= input();
        scanf(
"%d"&k);
        
while (k--{
            scanf(
"%d%d"&y, &x);
            map[y][x] 
= '@';
        }

        printf(
"Case %d: %d\n", c, bfs(t));
    }


    
return 0;
}

你可能感兴趣的:(POJ 1324 Holedox Moving 贪食蛇)