您的位置:首页 > 其它

HDU 1180诡异的楼梯

2014-06-07 23:25 393 查看
       链接:http://acm.hdu.edu.cn/showproblem.php?pid=1180

      这道题做了好久,好几天了,终于算是过了,哎,菜鸟的我越来越。。。。

      这个楼梯是可以转动的,每分钟变一次方向,所以要考虑的是走到楼梯前的时候楼梯所处的状态到底能不能过楼梯,很显然这道题BFS比较容易,但是这个楼梯的状态,真的是绕死我了,一直卡在这好几天,找学长帮我看,告诉我楼梯状态考虑错了,改了之后才过。

     楼梯状态判断:

bool floor(point cur,char x,int i)   //判断是否等楼梯
{
cur.time+=1;
if(x=='|')
{
if((i%2==0 && cur.time%2==0)||(i%2==1&&cur.time%2==1))
return 1;

return 0;
}
else if(x=='-')
{
if((i%2==1 && cur.time%2==0)||(i%2==0&&cur.time%2==1))
return 1;

return 0;
}
}


 

代码:

#include<cstdio>
#include<cstring>
#include<queue>

using std::queue;

int visit[22][22];
int n,m;
char map[22][22];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
struct point
{
int x,y,time;
}start;

bool floor(point cur,char x,int i)   //判断是否等楼梯
{
cur.time+=1;
if(x=='|')
{
if((i%2==0 && cur.time%2==0)||(i%2==1&&cur.time%2==1))
return 1;

return 0;
}
else if(x=='-')
{
if((i%2==1 && cur.time%2==0)||(i%2==0&&cur.time%2==1))
return 1;

return 0;
}
}

int BFS(int a,int b)
{
int i;
queue<point> q;
point cur,next;

memset(visit,0,sizeof(visit));
start.x=a;
start.y=b;
start.time=0;

q.push(start);

while(!q.empty())
{
cur=q.front();
q.pop();

if(map[cur.x][cur.y]=='T')
return cur.time;
for(i=0;i<n;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<m&&!visit[next.x][next.y]&&map[next.x][next.y]!='*')
{
if(map[next.x][next.y]=='.'||map[next.x][next.y]=='T')
{
visit[next.x][next.y]=1;
next.time=cur.time+1;
q.push(next);
}

else
{
int dx=next.x+dir[i][0];
int dy=next.y+dir[i][1];

if(dx>=0&&dx<n&&dy>=0&&dy<m&&!visit[dx][dy]&&map[dx][dy]!='*')//确保楼梯对面没被访问过
{
if(floor(cur,map[next.x][next.y],i))
{
next.x+=dir[i][0];
next.y+=dir[i][1];
next.time=cur.time+1;
visit[next.x][next.y]=1;
q.push(next);
}

else
{
next.x=cur.x;
next.y=cur.y;
next.time=cur.time+1;
q.push(next);
}
}
}
}
}
}
return -1;
}

int main()
{
int si,sj,i,j;

while(scanf("%d%d",&n,&m)!=EOF)
{
getchar();

for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%c",&map[i][j]);

if(map[i][j]=='S')
{
si=i;
sj=j;
}
}
getchar();
}

map[si][sj]='*';
printf("%d\n",BFS(si,sj));
}
return 0;
}


     还有一个学长写的代码,用了一个三维数组来记录楼梯状态,也贴下代码吧。

    代码:

#pragma warning(disable:4996)
#include <cstdio>
#include <queue>
#include <cstring>
using std::queue;
struct Node{
int r, c, t;
};
char map[22][22];
const int dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
int m, n, dis[22][22][2], sr, sc;
int BFS(){
memset(dis, 0x3f, sizeof(dis));
queue<Node> que;
Node curNode, nextNode;
curNode.r = sr;
curNode.c = sc;
curNode.t = 0;
dis[curNode.r][curNode.c][0] = 0;
que.push(curNode);
while (!que.empty()){
curNode = que.front();
que.pop();
for (int i = 0; i < 4; i++){
nextNode.r = curNode.r + dir[i][0];
nextNode.c = curNode.c + dir[i][1];
nextNode.t = curNode.t + 1;
if (map[nextNode.r][nextNode.c] == '-' || map[nextNode.r][nextNode.c] == '|'){
if (curNode.t % 2 == (i + (map[nextNode.r][nextNode.c] == '|')) % 2
&& map[nextNode.r + dir[i][0]][nextNode.c + dir[i][1]] != '*'){
nextNode.r += dir[i][0];
nextNode.c += dir[i][1];
}
else{
nextNode.r -= dir[i][0];
nextNode.c -= dir[i][1];
}
}
if (map[nextNode.r][nextNode.c] == 'T')
return nextNode.t;
if (map[nextNode.r][nextNode.c] == '*'){
nextNode.r -= dir[i][0];
nextNode.c -= dir[i][1];
}
if (dis[nextNode.r][nextNode.c][nextNode.t % 2] > nextNode.t){
dis[nextNode.r][nextNode.c][nextNode.t % 2] = nextNode.t;
que.push(nextNode);
}
}
}
}
int main(){
while (~scanf("%d%d", &m, &n)){
for (int i = 0; i <= n + 1; i++){
map[0][i] = map[m + 1][i] = '*';
}
for (int i = 0; i <= m + 1; i++){
map[i][0] = map[i][n + 1] = '*';
}
for (int i = 1; i <= m; i++){
getchar();
for (int j = 1; j <= n; j++){
scanf("%c", &map[i][j]);
if (map[i][j] == 'S'){
sr = i; sc = j;
}
}
}
printf("%d\n", BFS());
}
return 0;
}


 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BFS