杭電1180——詭異的樓梯(BFS+優先佇列)
阿新 • • 發佈:2019-02-16
主要演算法:遇到樓梯時,如果樓梯方向和前進方向一致且通過樓梯的下一格能走,則前進且時間加一。如果樓梯方向和前進方向不一致,則在原地等一分鐘。 至於樓梯方向的判斷,無需每時每刻都改變一下樓梯的方向,只需根據當前時間,如果時間為偶數,則樓梯方向與初始方向一樣,如果時間為奇數,則樓梯方向和初始方向相反。ps:做了快兩天一直WA,怎麼都看不出演算法哪裡有問題,後來發現題目中寫的輸入是多組資料,我只處理一組資料,看清題目啊.....
# include<iostream>
# include<queue>
using namespace std;
char maze[22 ][22];
int visited[22][22];
int waited[22][22];
int m,n,startx,starty,endx,endy;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
typedef struct Point{
int x,y,time;//橫座標x,縱座標y,時間time
bool operator <(const Point &p) const{
return time>p.time;//最小值優先
}
}Point;
priority_queue<Point> q ;
int bfs();
int main()
{
while(cin>>m>>n)
{
if(m==0&&n==0)
continue;
int i,j;
memset(visited,0,sizeof(int)*22*22);
memset(waited,0,sizeof(int)*22*22);
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cin>>maze[i][j];
if (maze[i][j]=='S')
{
startx=i;
starty=j;
}
else if(maze[i][j]=='T')
{
endx=i;
endy=j;
}
}
}
printf("%d\n",bfs());
}
return 0;
}
int bfs()
{
Point t,nt;
t.x=startx;
t.y=starty;
t.time=0;
q.push(t);
visited[startx][starty]=1;
while(!q.empty())
{
t=q.top();
q.pop();
if(t.x==endx&&t.y==endy)
return t.time;
int nx,ny,k;
for(k=0;k<4;k++)
{
nx=t.x+dir[k][0];
ny=t.y+dir[k][1];
if(nx>=0&&nx<m&&ny>=0&&ny<n&&maze[nx][ny]!='*'&&!visited[nx][ny])
{
if(maze[nx][ny]=='.'||maze[nx][ny]=='T')
{
nt.x=nx;
nt.y=ny;
nt.time=t.time+1;
visited[nx][ny]=1;
q.push(nt);
}
//待擴充套件的節點為樓梯
else if(maze[nx][ny]=='|'||maze[nx][ny]=='-')
{
//往左右方向擴充套件
if(k/2)
{
//此時樓梯方向為'-',與擴充套件方向一致,時間加一既可
if((maze[nx][ny]=='-'&&!(t.time%2))||(maze[nx][ny]=='|'&&t.time%2))
{
if(ny>=-dir[k][1]&&ny<n-dir[k][1]&&maze[nx][ny+dir[k][1]]!='*'&&!visited[nx][ny+dir[k][1]])
{
nt.x=nx;
nt.y=ny+dir[k][1];
visited[nt.x][nt.y]=1;
nt.time=t.time+1;
q.push(nt);
}
}
else if(!waited[t.x][t.y])
{
nt.x=t.x;
nt.y=t.y;
visited[nt.x][nt.y]=1;
waited[nt.x][nt.y]=1;
nt.time=t.time+1;//在原地等一分鐘
q.push(nt);
}
}
//上下方向擴充套件
else
{
//樓梯方向為'|',擴充套件方向與樓梯方向一致
if((maze[nx][ny]=='|'&&!(t.time%2))||(maze[nx][ny]=='-'&&t.time%2))
{
if(nx>=-dir[k][0]&&nx<m-dir[k][0]&&maze[nx+dir[k][0]][ny]!='*'&&!visited[nx+dir[k][0]][ny])
{
nt.x=nx+dir[k][0];
nt.y=ny;
visited[nt.x][nt.y]=1;
nt.time=t.time+1;
q.push(nt);
}
}
else if(!waited[t.x][t.y])
{
nt.x=t.x;
nt.y=t.y;
visited[nt.x][nt.y]=1;
waited[nt.x][nt.y]=1;
nt.time=t.time+1;
q.push(nt);
}
}
}
}
}
}
return 0;
}