您的位置:首页 > 其它

UVA 10047 The Monocycle

2015-11-06 00:52 393 查看
白书上图论例题2

题目大意是 M*N个格子 #不能走

S是起点 T是终点

上北下南左西右东

一开始在S,朝向北,

在每一个格子 可以左转90度 或者右转90度 或者朝向走1格

问从起点到终点 计算重复格子 走5的整数倍个格子到终点 不限制最后朝向 最短时间是多少

就像书上讲的那样

每个点 拆成20个点

(x,y,color,head)

分别表示该点的坐标,走到该点 走过的格子%5,现在的朝向

每次可以向(x,y,color,head-1) (x,y,color,head+1) (x+mx[head],y+my[head],(color+1)%5,head)走

分别对应左转、右转和前进

因为每次操作都是花费1

所以直接bfs也可以 先搜到的终点一定是时间最少的

这样还有一个好处就是不用扔set了 判重也方便

其实这个不用set也可以。。。

发现现在有点依赖stl了。。。

这个题还有一个坑点 就是 每两组数据间输出一个空行

但是最后一组只能有1个空行!

我用spfa写的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<queue>
using namespace std;
const int lim = 26;
const int lin = lim*lim*lim*lim*lim;
const int inf = 0x3f3f3f3f;
const int mx[4]={-1,0,1,0};
const int my[4]={0,1,0,-1};

int g[lim][lim];

struct node
{
int x,y,color,head;
node()
{
x=y=color=head=0;
}
node(int xx,int yy,int col,int hea)
{
x=xx;
y=yy;
color=col;
head=hea;
}
bool operator<(const node h) const
{
if(h.x==x)
if(h.y==y)
if(h.color==color)
return h.head<head;
else
return h.color<color;
else
return h.y<y;
else
return h.x<x;
}
};

node S,T;

map<node,int>mp;

queue<node>q;
int d[lim*lim*20];
int vis[lim*lim*20];
int fst[lim*lim*20];
int m,n;
int r,c;
char chin;
int _case;

void spfa()
{
while(!q.empty())
q.pop();
memset(d,0x3f,sizeof(d));
memset(vis,0,sizeof(vis));
q.push(S);
mp[S]=++m;
vis[m]=1;
d[m]=0;
while(!q.empty())
{
node u=q.front();
q.pop();
int uid=mp[u];
vis[uid]=0;

int x=u.x;
int y=u.y;
int color=u.color;
int head=u.head;
for(int i=-1;i<=1;i+=2)
{
int hhead=(head+i+4)%4;
node v = node(x,y,color,hhead);
if(mp[v]==0)
{
mp[v]=++m;
}
int vid=mp[v];
if(d[vid]>d[uid]+1)
{
d[vid]=d[uid]+1;
if(!vis[vid])
{
vis[vid]=1;
q.push(v);
}
}
}

int xx=x+mx[head],yy=y+my[head];
int ccolor=(color+1)%5;
if(xx>=1 && xx<=r && yy>=1 && yy<=c && g[xx][yy]==1)
{
node v = node(xx,yy,ccolor,head);
if(mp[v]==0)
{
mp[v]=++m;
}
int vid=mp[v];
if(d[vid]>d[uid]+1)
{
d[vid]=d[uid]+1;
if(!vis[vid])
{
vis[vid]=1;
q.push(v);
}
}
}
}
int ans = inf;
for(int k=0;k<=3;k++)
{
node tt = node(T.x,T.y,0,k);
ans=min(ans,d[mp[tt]]);
}
if(ans==inf)
{
printf("Case #%d\ndestination not reachable\n",_case);
}
else
{
printf("Case #%d\nminimum time = %d sec\n",_case,ans);
}
}
int main()
{
while(scanf("%d%d",&r,&c)==2)
{
if(r==0 && c==0)
return 0;
if(_case>=1)
printf("\n");
m=0;
mp.clear();
_case++;
memset(fst,-1,sizeof(fst));
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf(" %c",&chin);
if(chin=='#')
g[i][j]=0;
else
{
g[i][j]=1;
if(chin=='S')
{
S.x=i;
S.y=j;
S.color=0;
S.head=0;
}
if(chin=='T')
{
T.x=i;
T.y=j;
T.color=0;
}
}
}
}
spfa();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: