糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

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;
}

posted on 2010-04-17 20:47 糯米 阅读(721) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理