【模拟】jzoj1432输油管道 纪中集训提高B组
Description
请你帮忙设计一个从城市M到城市Z的输油管道,现在已经把整个区域划分为R行C列,每个单元格可能是空的也可能是以下7种基本管道之一:
油从城市M流向Z,‘+’型管道比较特殊,因为石油必须在两个方向(垂直和水平)上传输,如下图所示:
现在恐怖分子弄到了输油管道的设计图,并把其中一个单元格中的管道偷走了,请你帮忙找到偷走的管道的位置以及形状。
Input
第一行包含两个整数R和C(1<=R,C<=25)。
接下来R行每行C个字符描述被偷之后的形状,字符分为以下三种:
(1)‘.’表示空;
(2)字符‘|’(ASCII为124)、‘-’、‘+’、‘1’、‘2’、‘3’、‘4’描述管道的形状;
(3)‘M’和‘Z’表示城市,两个都是只出现一次。
输入保证石油的流向是唯一的,只有一个管道跟M和Z相连,除此此外,保证没有多余的管道,也就是说所有的管道在加进被偷的管道后一定都会被用上。
输入保证有解而且是唯一的。
Output
输出被偷走的管道的行号和列号以及管道的类型。
Sample Input
输入1:
3 7
…
.M-.-Z.
…
输入2:
3 5
…1-M
1-+…
Z.23.
输入3:
6 10
Z.1----4…
|.|…|…
|…14…M…
2-+++4…
…2323…
…
Sample Output
输出1:
2 4 -
输出2:
2 4 4
输出3:
3 3 |
特别简单的模拟题,但是细节特别多,写出了数据结构的码量。
直接从起点开始顺着走,找到需要接管子的地方就可以了,但注意接的类型要跟接口的地方匹配,考场上就忘记了判断这个。
比如说这种数据:
6 6
.14...
.|2.4.
.|.1+4
.|.23|
1+4..|
232M.Z
2 4 -
2,4那个点周围就有很多个管子(因为’+’),但是只能横着走,不能竖着走,因为它接不上下面的那个1
还特判了一组只差一个管子就到达终点的情况,就是最开始起点周围没有管子,结果没有这样的数据。
嘤嘤嘤,我再也不手动开氧气了,开了氧气玄学0分,不开氧气有66分,这样我就上200了,哭唧唧。
对了,看到讨论里面有人在说利用二进制来表示:四位二进制数表示上下左右是否联通,然后对应到管道上去,比如说1111就可以表示’+ '(这个例子是不是太极端了) ,然后就可以很简洁地模拟。但是我没有试过,我再也不想碰这种毒瘤模拟题了 。
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 30
#define LL long long
char s[MAXN][MAXN];
int vis[MAXN][MAXN];
int n,m,sx,sy,tx,ty;
const int dx[]={-1,1,0,0},dy[]={0,0,1,-1};//上下右左
bool check(int x,int y)
{
if(s[x][y]=='.'||s[x][y]=='Z'||x<1||x>n||y<1||y>m)
return 0;
if(s[x][y]!='+'&&vis[x][y])
return 0;
if(s[x][y]=='+'&&vis[x][y]==2)
return 1;
}
bool down(int x,int y)
{
if(s[x][y]=='|'||s[x][y]=='+'||s[x][y]=='2'||s[x][y]=='3')
return 1;
return 0;
}
bool up(int x,int y)
{
if(s[x][y]=='|'||s[x][y]=='+'||s[x][y]=='1'||s[x][y]=='4')
return 1;
return 0;
}
bool rt(int x,int y)
{
if(s[x][y]=='-'||s[x][y]=='+'||s[x][y]=='3'||s[x][y]=='4')
return 1;
return 0;
}
bool lft(int x,int y)
{
if(s[x][y]=='-'||s[x][y]=='+'||s[x][y]=='1'||s[x][y]=='2')
return 1;
return 0;
}
int main()
{
scanf("%d %d",&n,&m);
for(register int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for(register int j=1;j<=m;j++)
{
if(s[i][j]=='M') sx=i,sy=j;
if(s[i][j]=='Z') tx=i,ty=j;
}
}
int nx=sx,ny=sy,d=4;
for(int i=0;i<4;i++)
if(check(nx+dx[i],ny+dy[i]))
{
nx=nx+dx[i];
ny=ny+dy[i];
d=i;
break;
}
//----特判M.Z的情况
if(d==4)
{
if(sx==tx)
{
if(sy+2==ty)
{
printf("%d %d -",sx,sy+1);
return 0;
}
if(sy-2==ty)
{
printf("%d %d -",sx,sy-1);
return 0;
}
}
if(sy==ty)
{
if(sx+2==tx)
{
printf("%d %d -",sx+1,sy);
return 0;
}
if(sx-2==tx)
{
printf("%d %d -",sx-1,sy);
return 0;
}
}
if(tx==sx-1&&ty==sy+1)
{
printf("%d %d 1",sx-1,sy);
return 0;
}
if(tx==sx+1&&ty==sy-1)
{
printf("%d %d 1",sx,sy-1);
return 0;
}
if(tx==sx+1&&ty==sy+1)
{
printf("%d %d 2",sx+1,sy);
return 0;
}
if(tx==sx-1&&ty==sy-1)
{
printf("%d %d 2",sx,sy-1);
return 0;
}
if(tx==sx-1&&ty==sy+1)
{
printf("%d %d 3",sx,sy+1);
return 0;
}
if(tx==sx+1&&ty==sy-1)
{
printf("%d %d 3",sx-1,sy);
return 0;
}
if(tx==sx+1&&ty==sy+1)
{
printf("%d %d 4",sx,sy+1);
return 0;
}
if(tx==sx-1&&ty==sy-1)
{
printf("%d %d 4",sx-1,sy);
return 0;
}
}
//----
//printf("%d %d %d\n",nx,ny,d);
while(s[nx][ny]!='.')
{
//printf("%d %d\n",nx,ny);
vis[nx][ny]++;
if(s[nx][ny]=='|')
{
if(d==1) nx++,d=1;
if(d==0) nx--,d=0;
continue;
}
if(s[nx][ny]=='-')
{
if(d==2) ny++,d=2;
if(d==3) ny--,d=3;
continue;
}
if(s[nx][ny]=='+')
{
if(d==1) nx++,d=1;
if(d==0) nx--,d=0;
if(d==2) ny++,d=2;
if(d==3) ny--,d=3;
continue;
}
if(s[nx][ny]=='1')
{
if(d==0) ny++,d=2;
if(d==3) nx++,d=1;
continue;
}
if(s[nx][ny]=='2')
{
if(d==1) ny++,d=2;
if(d==3) nx--,d=0;
continue;
}
if(s[nx][ny]=='3')
{
if(d==2) nx--,d=0;
if(d==1) ny--,d=3;
continue;
}
if(s[nx][ny]=='4')
{
if(d==2) nx++,d=1;
if(d==0) ny--,d=3;
continue;
}
}
printf("%d %d ",nx,ny);
int d2=4;
int mark=0;
for(int i=0;i<4;i++)
{
int x=nx+dx[i],y=ny+dy[i];
if(s[x][y]=='.'||x<1||x>n||y<1||y>m) continue;
else mark++;
}
if(mark==4)
{
printf("+");
return 0;
}
for(int i=0;i<4;i++)
if(check(nx+dx[i],ny+dy[i]))
{
d2=i;
if((d==0&&d2==0&&up(nx+dx[i],ny+dy[i]))||(d==1&&d2==1&&down(nx+dx[i],ny+dy[i])))
{
printf("|");
break;
}
if((d==2&&d2==2&&rt(nx+dx[i],ny+dy[i]))||(d==3&&d2==3&&(lft(nx+dx[i],ny+dy[i]))))
{
printf("-");
break;
}
if((d==0&&d2==2&&rt(nx+dx[i],ny+dy[i]))||(d==3&&d2==1&&down(nx+dx[i],ny+dy[i])))
{
printf("1");
break;
}
if((d==1&&d2==2&&rt(nx+dx[i],ny+dy[i]))||(d==3&&d2==0&&up(nx+dx[i],ny+dy[i])))
{
printf("2");
break;
}
if((d==2&&d2==0&&up(nx+dx[i],ny+dy[i]))||(d==1&&d2==3&&lft(nx+dx[i],ny+dy[i])))
{
printf("3");
break;
}
if((d==2&&d2==1&&down(nx+dx[i],ny+dy[i]))||(d==0&&d2==3)&&lft(nx+dx[i],ny+dy[i]))
{
printf("4");
break;
}
//break;
}
return 0;
}