E、尼比市的决斗
theme:给定n*n的迷宫,S、T为起点、终点,#代表墙,.代表可以走,最外一层保证是墙,S的下方一个一定是墙。要求从S开始每次右边贴着墙壁走,保证一定能走到T,输出从S到T贴着的墙壁的相对方位。
solution:有一点麻烦的模拟。
每一个位置对应3中情况:【以往右为例】
(1)右边一个是墙,则下一步往上转向
(2)有一个不为墙,右下方为墙,则可以往右走一个
(3)右方与右下方都不为墙,则下一步往右下拐
每个行进方向对于3种情况,总共12种,我们可以用数组记录下每一行进方向的每一种情况对应的坐标与方向的改变情况。
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<map>
#include<vector>
typedef long long ll;
#define far(i,t,n) for(int i=t;i<n;++i)
using namespace std;
struct _a
{
int i,x,y;
_a (int j,int a,int b)
{
i=j;
x=a;
y=b;
}
};
char a[20][20];
char d[4]= {'D','L','U','R'};//R0,D1,L2,U3
vector<_a>v[5];
int main()
{
int n;
cin>>n;
int sx,sy,ex,ey;
far(i,0,n)
scanf("%s",a[i]);
far(i,0,n)
far(j,0,n)
{
if(a[i][j]=='S')
sx=i,sy=j;
if(a[i][j]=='T')
ex=i,ey=j;
}
v[0].push_back(_a(3,-1,0)),v[0].push_back(_a(0,0,1)),v[0].push_back(_a(1,1,0));
v[1].push_back(_a(0,0,1)),v[1].push_back(_a(1,1,0)),v[1].push_back(_a(2,0,-1));
v[2].push_back(_a(1,1,0)),v[2].push_back(_a(2,0,-1)),v[2].push_back(_a(3,-1,0));
v[3].push_back(_a(2,0,-1)),v[3].push_back(_a(3,-1,0)),v[3].push_back(_a(0,0,1));
int x=sx,y=sy,flag=0;
printf("D");
while(x!=ex||y!=ey)
{
// cout<<flag<<" "<<x<<" "<<y<<endl;
if(a[x+v[flag][1].x][y+v[flag][1].y]=='T')
{
if(a[x+v[flag][1].x+v[flag][2].x][y+v[flag][1].y+v[flag][2].y]=='#')
printf("%c",d[flag]);
break;
}
if(a[x+v[flag][1].x+v[flag][2].x][y+v[flag][1].y+v[flag][2].y]=='T')
{
printf("%c",d[v[flag][2].i]);
break;
}
if(a[x+v[flag][1].x][y+v[flag][1].y]=='#')
{
//cout<<"1: "<<x+v[flag][1].x<<" "<<y+v[flag][1].y<<endl;
flag=v[flag][0].i;
printf("%c",d[flag]);
}
else if(a[x+v[flag][1].x+v[flag][2].x][y+v[flag][1].y+v[flag][2].y]=='#')
{
// cout<<"2: "<<x+v[flag][1].x+v[flag][2].x<<" "<<y+v[flag][1].y+v[flag][2].y<<endl;
printf("%c",d[flag]);
x=x+v[flag][1].x;
y=y+v[flag][1].y;
}
else
{
// cout<<"3: "<<x+v[flag][1].x+v[flag][2].x<<" "<<y+v[flag][1].y+v[flag][2].y<<endl;
x=x+v[flag][1].x+v[flag][2].x;
y=y+v[flag][1].y+v[flag][2].y;
flag=v[flag][2].i;
printf("%c",d[flag]);
}
}
printf("\n");
}