HDU 5040 BFS+状压

来源:互联网 发布:淘宝涛哥电玩店 编辑:程序博客网 时间:2024/04/28 21:27

2014 ACM/ICPC Asia Regional Beijing Online

对于N*N的矩阵

M起点,T终点

有起始方向分别向北N,东E,南S,西W的摄像头,可以检测的范围为自己+所指方向1格,每1秒顺时针旋转90°

前面有灯或者自己站的地方有灯,移动需要花3秒,或者原地等一秒。


BFS优先队列

开3维 hash数组判重,第三维是在该点等待的时间,开到4即可(摄像头转一圈)

对图中的每个点提前处理处会在什么时候被摄像头看到,用2进制压缩存储在MAP数组中

然后常规BFS解决

比赛时候手残没写CASE。。。。找了半天错误。。。。。

/*                   _ooOoo_                  o8888888o                  88" . "88                  (| -_- |)                  O\  =  /O               ____/`---'\____             .'  \\|     |//  `.            /  \\|||  :  |||//  \           /  _||||| -:- |||||-  \           |   | \\\  -  /// |   |           | \_|  ''\---/''  |   |           \  .-\__  `-`  ___/-. /         ___`. .'  /--.--\  `. . __      ."" '<  `.___\_<|>_/___.'  >'"".     | | :  `- \`.;`\ _ /`;.`/ - ` : | |     \  \ `-.   \_ __\ /__ _/   .-` /  /======`-.____`-.___\_____/___.-`____.-'======                   `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^         fozubaoyou    pass System Test!*/#include "stdio.h"#include "string.h"#include "queue"using namespace std;int inf=0x3f;int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};struct node{    int x,y,step,wait; // step记录步数,wait记录等待的时间    friend bool operator<(node n1,node n2)    {        return n1.step>n2.step;    }};int s_x,s_y,n;int b[5];char str[510][510]; int map[510][510],hash[510][510][5]; // MAP 存储每个点什么时候会被看到,HASH判重第三维是在该点等待的时间int bfs(){    priority_queue<node>q;    node cur,next;    int i,time;    cur.x=s_x;    cur.y=s_y;    cur.step=0;    cur.wait=0;    q.push(cur);    memset(hash,inf,sizeof(hash));    hash[cur.x][cur.y][0]=0;    while (!q.empty())    {        cur=q.top();        q.pop();        if (str[cur.x][cur.y]=='T') return cur.step;        for (i=0;i<4;i++)        {            next.x=cur.x+dir[i][0];            next.y=cur.y+dir[i][1];            if (next.x<0 || next.x>=n || next.y<0 || next.y>=n) continue;            if (str[next.x][next.y]=='#') continue;            time=b[cur.step%4];            if ((map[cur.x][cur.y]&time)==time || (map[next.x][next.y]&time)==time) // 当前点或下一个点会被看到                next.step=cur.step+3;            else                next.step=cur.step+1;            next.wait=0;            if (next.step<hash[next.x][next.y][next.wait])            {                q.push(next);                hash[next.x][next.y][next.wait]=next.step;            }        }        next.x=cur.x;        next.y=cur.y;        next.step=cur.step+1;        next.wait=cur.wait+1;        if (next.wait<=3  && next.step<hash[next.x][next.y][next.wait]) // 原地等待        {            q.push(next);            hash[next.x][next.y][next.wait]=next.step;        }    }    return -1;}int main(){    int Case,ii,i,j;    scanf("%d",&Case);    b[0]=1; b[1]=2; b[2]=4; b[3]=8;    for (ii=1;ii<=Case;ii++)    {        scanf("%d",&n);        getchar();        for (i=0;i<n;i++)            gets(str[i]);        printf("Case #%d: ",ii);        memset(map,0,sizeof(map));        for (i=0;i<n;i++) // 状压存储每个点什么时候会被看到            for (j=0;j<n;j++)            {                if (str[i][j]=='M') { s_x=i; s_y=j;}                if (str[i][j]=='N')                {                    map[i][j]=15;                    if (i-1>=0) map[i-1][j]|=1;                    if (j+1<n)  map[i][j+1]|=2;                    if (i+1<n)  map[i+1][j]|=4;                    if (j-1>=0) map[i][j-1]|=8;                }                if (str[i][j]=='E')                {                    map[i][j]=15;                    if (j+1<n)  map[i][j+1]|=1;                    if (i+1<n)  map[i+1][j]|=2;                    if (j-1>=0) map[i][j-1]|=4;                    if (i-1>=0) map[i-1][j]|=8;                }                if (str[i][j]=='S')                {                    map[i][j]=15;                    if (i+1<n)  map[i+1][j]|=1;                    if (j-1>=0) map[i][j-1]|=2;                    if (i-1>=0) map[i-1][j]|=4;                    if (j+1<n)  map[i][j+1]|=8;                }                if (str[i][j]=='W')                {                    map[i][j]=15;                    if (j-1>=0) map[i][j-1]|=1;                    if (i-1>=0) map[i-1][j]|=2;                    if (j+1<n)  map[i][j+1]|=4;                    if (i+1<n)  map[i+1][j]|=8;                }            }        printf("%d\n",bfs());    }    return 0;}




1 0
原创粉丝点击