神殿
jzoj 2296
题目大意:
用一个n∗mn*mn∗m的矩阵,每个单位都是一个1∗11*11∗1的房间,房间的四个方向只有某些方向有门(说明如下图),要从一个房间走向相邻的房间(算一个单位时间)必须要他们中间的两个门都是存在,也可以把所有房间的门顺时针旋转一轮(算一个单位时间),现在问从(x1,y1)(x_1,y_1)(x1,y1)走到(x2,y2)(x_2,y_2)(x2,y2)最少需要多少各单位时间
输入样例#1
2 2
+*
*U
1 1 2 2
输出样例#1
-1
输入样例#2
2 3
<><
><>
1 1 2 1
输出样例#2
4
数据范围
对于30%的数据,满足n,m⩽10n,m \leqslant 10n,m⩽10。
对于50%的数据,满足n,m⩽50n,m \leqslant 50n,m⩽50。
对于另外20%的数据,满足没一个房间要么只有一个方向没门,要么一个方向上的门都没有。
对于100%的数据,满足n,m⩽1000n,m \leqslant 1000n,m⩽1000。
注
题目标中的特殊符号:
<>^v+*|-
解题思路:
直接bfs去跑,每一次要么旋转,要么走,这样时间复杂度就是o(4nm)o(4nm)o(4nm)(整个图加上旋转的四种情况)
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};
int n,m,x1,x2,y1,y2,a[1500][1500][5],p[1500][1500][5];
char x;
struct rec
{int x,y,r,num;
};
void input()//输入
{scanf("%d %d",&n,&m);for (int i=1;i<=n;++i){getchar();for (int j=1;j<=m;++j){x=getchar();if (x=='+') a[i][j][0]=1,a[i][j][1]=1,a[i][j][2]=1,a[i][j][3]=1;//判断每一种情况else if (x=='-') a[i][j][1]=1,a[i][j][3]=1;else if (x=='|') a[i][j][0]=1,a[i][j][2]=1;else if (x=='^') a[i][j][0]=1;else if (x=='>') a[i][j][3]=1;else if (x=='<') a[i][j][1]=1;else if (x=='v') a[i][j][2]=1;else if (x=='L') a[i][j][0]=1,a[i][j][2]=1,a[i][j][3]=1;else if (x=='R') a[i][j][0]=1,a[i][j][1]=1,a[i][j][2]=1;else if (x=='U') a[i][j][1]=1,a[i][j][2]=1,a[i][j][3]=1;else if (x=='D') a[i][j][0]=1,a[i][j][1]=1,a[i][j][3]=1;}}scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
}
bool check(rec gg,int f)
{if (!p[gg.x+dx[f]][gg.y+dy[f]][gg.r])//判断是否到过if (a[gg.x][gg.y][(f+gg.r)%4] && a[gg.x+dx[f]][gg.y+dy[f]][(f+gg.r+2)%4])//判断是否两道门都开if(gg.x+dx[f]>0 && gg.x+dx[f]<=n && gg.y+dy[f]>0 && gg.y+dy[f]<=m)//判断是否超界return true;return false;
}
void bfs()
{queue<rec>d;rec o;o.x=x1;o.y=y1;o.num=0;//时间o.r=0;//旋转次数d.push(o);p[x1][y1][0]=1;if (o.x==x2&&o.y==y2){printf("0");return;}while(!d.empty()){rec h=d.front();d.pop();if (!p[h.x][h.y][(h.r+1)%4])//旋转{rec o;o.x=h.x;o.y=h.y;o.num=h.num+1;o.r=(h.r+1)%4;p[o.x][o.y][o.r]=1;d.push(o);}for (int i=0;i<4;++i)//往某个方向走if (check(h,i)){rec o;o.x=h.x+dx[i];o.y=h.y+dy[i];o.r=h.r;o.num=h.num+1;p[o.x][o.y][o.r]=1;d.push(o);if (o.x==x2&&o.y==y2){printf("%d",o.num);return;}}}printf("-1");
}
int main()
{input();bfs();
}