【模拟】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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值