1. 程式人生 > >HDU 1180詭異的樓梯

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

相關推薦

HDU 1180 詭異樓梯 (搜索)

put rst php 代碼 出現 http 表示 朋友 turn 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1180 TLE n次。。 註意兩點:1,S.T這三種位置是可以停留一秒的。即在沒有路可走的時候可以停留一秒。

HDU 1180 詭異樓梯(超級經典的bfs之一,需多回顧)

改變 .... ref ret accept 每次 while lec img 傳送門: http://acm.hdu.edu.cn/showproblem.php?pid=1180 詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)

HDOJ/HDU 1180 詭異樓梯(經典BFS-詳解)

Problem Description Hogwarts正式開學以後,Harry發現在Hogwarts裡,某些樓梯並不是靜止不動的,相反,他們每隔一分鐘就變動一次方向. 比如下面的例子裡,一開始樓梯在豎直方向,一分鐘以後它移動到了水平方向,再過一分鐘它又回到

HDU 1180詭異樓梯

      這道題做了好久,好幾天了,終於算是過了,哎,菜鳥的我越來越。。。。       這個樓梯是可以轉動的,每分鐘變一次方向,所以要考慮的是走到樓梯前的時候樓梯所處的狀態到底能不能過樓梯,很顯然這道題BFS比較容易,但是這個樓梯的狀態,真的是繞死我了,一直卡在這好幾

HDU 1180 詭異樓梯(BFS+優先佇列)

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 13186    Accepted Submis

【搜尋之BFS + 優先佇列】杭電 hdu 1180 詭異樓梯

/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2012

hdu 1180 詭異樓梯(bfs+優先佇列)

詭異的電梯,實在詭異!!! 分析到詭異的地方時,把我都搞迷了! 看你別人的程式碼!才知道這樣分析!!! 這題關鍵判斷電梯的方向!!!人可以為了減少時間停在原地不動等電梯改變方向!!! #include<stdio.h> #include<string.h

hdu 1180 詭異樓梯

#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int n,m; int qx,qy,jx,jy; char map[3

hdu 1180 詭異樓梯 (bfs)

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 9360    Accepted Submis

HDU 1180 詭異樓梯

Input 測試資料有多組,每組的表述如下: 第一行有兩個數,M和N,接下來是一個M行N列的地圖,'*'表示障礙物,'.'表示走廊,'|'或者'-'表示一個樓梯,並且標明瞭它在一開始時所處的位置:'|'表示的樓梯在最開始是豎直方向,'-'表示的樓梯在一開始是水平方向.地圖中還有一個'S'是起點,'T'是目標

hdu 1180 詭異樓梯 搜尋

7 地圖如下: 這個題的難點就是梯子每隔一分鐘改變一次方向,需要判斷梯子每個時刻的方向,確定遇見梯子直接可以走嗎,題上說可以在任何非梯子的地方停留,這樣就可以在遇見梯子不能直接走的時候在原地等一分鐘“登上樓梯並經過樓梯到達對面的整個過程只需要一分鐘”,如S.|T只需要兩分鐘,S到.

杭電acm 1180 詭異樓梯 BFS

script 朋友 mission emp temp ont pty content using 詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Other

1180 詭異樓梯

Hogwarts正式開學以後,Harry發現在Hogwarts裡,某些樓梯並不是靜止不動的,相反,他們每隔一分鐘就變動一次方向.  比如下面的例子裡,一開始樓梯在豎直方向,一分鐘以後它移動到了水平方向,再過一分鐘它又回到了豎直方向.Harry發現對他來說很難找到能使得他最快到

杭電1180——詭異樓梯(BFS+優先佇列)

主要演算法:遇到樓梯時,如果樓梯方向和前進方向一致且通過樓梯的下一格能走,則前進且時間加一。如果樓梯方向和前進方向不一致,則在原地等一分鐘。 至於樓梯方向的判斷,無需每時每刻都改變一下樓梯的方向,只需根據當前時間,如果時間為偶數,則樓梯方向與初始方向一樣,如

HDU 2041 超級樓梯 簡單動態規劃

多少 .html div ++ n) 導出 can -- http 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2041題目大意:有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法?這

HDU-2041超級樓梯

HDU-2041超級樓梯 題目: 有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法? Input 輸入資料首先包含一個整數N,表示測試例項的個數,然後是N行資料,每行包含一個整數M(1<=M<=40),表示樓梯的級數。 Output

[遞推簡單dp]-hdu 2041 超級樓梯

[遞推簡單dp]-hdu 2041 超級樓梯 標籤: ACM 題意: 有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法? input 輸入資料首先包含一個整數N,表示測試例項的個數,然後是N行資料,

HDU-2041-超級樓梯(水/Fibonacci數列/找規律)

有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法? Input 輸入資料首先包含一個整數N,表示測試例項的個數,然後是N行資料,每行包含一個整數M(1<=M<=40),表示樓梯的級數。 Output 對於每個測試例

HDU 2041 超級樓梯 題解

由題意得: 1.這算是斐波那契數列 2.第一項與第二項的值為‘1’,從第三項開始,每一項的值為前兩項之和 3.程式碼如下: #include<iostream> using namespace std; int n,num,a[41]; int main() {

hdoj 詭異樓梯 1180 (bfs&&奇偶判斷) 好題

#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #define INF 0x3f3f3f3f using namespace std; char a[22][22]