【搜索】 来自风平浪静的明天

来自风平浪静的明天
【题目描述】
冬眠了五年,光终于从梦中醒来。
千咲、要,大家都在。
隐约记得“昨天”的海船祭,爱花意外成为贡女,沉入海底。
海面冰封,却有丝丝暖流在冰面之下涌动。
此时,爱花沉睡在祭海女神的墓地。她的胞衣在一点点脱落,化作一簇簇暖流,夹杂着她的感情,向海面上涌去。
爱花,你在哪里?
五年之后,纺已经成为海洋学研究科的大学生。
在纺的帮助下,光得知了海面下海流的情况。
纺告诉光,暖流一旦产生,就会不断地向四周扩散,直到遇到海中的岩石。
红腹海牛,快告诉光,爱花在哪里。
纺帮你绘制了一张海流情况图,长度为N,宽度为M。
海很大,一边有沙滩,一边一望无际,但长度和宽度都不会超过300。沙滩是金黄色的,所以用Y表示。海是蓝色的,所以用B表示。暖流很暖和,所以用H表示
海中有大大小小的石头。石头很危险,所以用X表示
光相信自己一定能找到爱花(爱花的位置只有一种可能)
【输入格式】
第一行包括两个整数N,M。
接下来N行,每行M个字符。
【输出格式】
仅一行,表示爱花的位置(如果你无能为力,请输出 -1 ,只要你尽力,光不会责怪你)
【样例输入】
5 5
YYYHB
YYHHH
YHHXB
BBHBB
BBBBB
【样例输出】
2 3
【数据范围】
对于30%的数据,n,m<=10
对于70%的数据,n,m<=100
对于100%的数据,n,m<=300
【样例解释】
在(2,3)出现第一个H后,经过3s后,出现样例输入的地图。
P.S. Mushroom拜托他GF出的这题= =

Solution:

对于每一个H点进行枚举。进行BFS扩展。扩展中遇见除了H以外的B区域则说明H点不是目标点。

这样的复杂度最差是n^n^n^n;

实际上 H点没有 n^n这么多。 而且BFS扩展中很容易扩展到B区域然后弹掉。

不知道为什么。这道题的数据很水。

因为判断H是目标点的条件是 num_bfs_H=tot_H

但是实际上 达到条件之后不能马上弹出check的过程

因为可能在满足上诉条件之后,还有1--3个方向中,存在B  显然弹出的情况是错误的。

然而我并没有管这个。实际上应该在num_bfs_H=tot_H而且当前层数的点全部BFS完之后,如果没有一个点扩展到B节点,才能判断枚举的H起始点合法。

吐槽一下出题人。。而且X“危险的时候”并没有什么卵用!!!这直接导致我BFS挂掉。

以下是代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int move_x[5]={-1,1,0,0};
int move_y[5]={0,0,-1,1};
int m,n,flag=0,tot;
int x_t[10000],y_t[10000];
int vis[301][301];
char g[301][301];
char ch[305];
int BFS (int sx,int sy)
{
	queue<int> q;
	int cnt=0,num=1;
	memset(x_t,0,sizeof(x_t));
	memset(y_t,0,sizeof(y_t));
	memset(vis,0,sizeof(vis));
	q.push(++cnt);x_t[cnt]=sx;y_t[cnt]=sy;vis[sx][sy]=1;
	while(!q.empty()){
		int k=q.front();q.pop();
		int x=x_t[k],y=y_t[k];
		for (int i=0;i<=3;i++){
			int x_n=x+move_x[i];
			int y_n=y+move_y[i];
			if(x_n<=m&&x_n>0&&y_n>0&&y_n<=m&&g[x_n][y_n]!='Y'&&g[x_n][y_n]!='X'&&vis[x_n][y_n]==0){
				if(g[x_n][y_n]=='H')
				{
					num++;
					vis[x_n][y_n]=1;
					q.push(++cnt);
					x_t[cnt]=x_n;y_t[cnt]=y_n;
					if(num==tot) 
						return 1;
				}
				else return 0;
			}
		}
	}
}
int main()
{
	freopen("calm.in","r",stdin);
	freopen("calm.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++){
		scanf("%s",ch+1);
		for (int j=1;j<=m;j++){
			g[i][j]=ch[j];
			if(ch[j]=='H') 
					tot++;
		}
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			if(g[i][j]=='H')
				if(BFS(i,j)){
					cout<<i<<' '<<j;
					return 0;
				}
	cout<<"-1";			
				
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值