HDU 1180詭異的樓梯

       鏈接: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;
}


 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章