列表

详情


NC220162. 跑步

描述

NIT走到了一片森林,这片森林可以抽象成一个n*m的矩阵。有一些地方长有树,NIT不能走到上面去。NIT可以上下左右或斜向八连通行走。

现在NIT想跑跑步锻炼身体,他想沿着一条路走然后回到起点。并且NIT想这条路径一定是一个至少包着一颗树的环。请问这条路径的最短长度是多少。

输入描述

第一行有三个整数n,m,q表示森林的长宽以及询问个数

接下来n行,每行m个字符,表示森林的情况。其中”.”表示空地,”X”表示树。

接下来q行每行两个数x,y表示NIT的起点(起点不会是树)保证有合法路径。

输出描述

输出q行,每行表示每个询问的最短路长度

示例1

输入:

6 7 3
.......
...X.X.
...X.X.
...XXX.
.X.....
.......
1 7
3 7
3 1

输出:

13
12
6

说明:

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 191ms, 内存消耗: 8268K, 提交时间: 2021-04-09 20:22:25

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=1005;
int a[MAXN][MAXN],s[MAXN][MAXN];
queue<int>q;
inline void sss(int x,int y,int z) {
	if(a[x][y]&&s[x][y]==0x3f3f3f3f) {
		s[x][y]=z;
		q.push(x<<15|y);
	}
}
int main() {
	int n,m,k,x,y;
	cin>>n>>m>>k;
	for(int i=1; i<=n; i++)for(int j=1; j<=m; j++) {
			char c=getchar();
			while(c!='.'&&c!='X')c=getchar();
			if(c=='.')a[i][j]=1;
		}
	for(int i=1; i<=k; i++) {
		int ans=0x3f3f3f3f;
		cin>>x>>y;
		memset(s,0x3f,sizeof(s));
		s[x][y]=0;
		q.push(x<<15|y);//将坐标x,y压到一个int里
		while(!q.empty()) {
			int u=q.front();
			q.pop();
			sss((u>>15)+1,(u&32767),s[u>>15][u&32767]+1);
			sss((u>>15)+1,(u&32767)+1,s[u>>15][u&32767]+1);
			sss((u>>15),(u&32767)+1,s[u>>15][u&32767]+1);
			sss((u>>15)-1,(u&32767)+1,s[u>>15][u&32767]+1);
			sss((u>>15)-1,(u&32767),s[u>>15][u&32767]+1);
			sss((u>>15)-1,(u&32767)-1,s[u>>15][u&32767]+1);
			sss((u>>15),(u&32767)-1,s[u>>15][u&32767]+1);
			sss((u>>15)+1,(u&32767)-1,s[u>>15][u&32767]+1);
		}
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++) {
				if(s[i][j]>s[i-1][j-1]||s[i][j]>s[i-1][j]||s[i][j]>s[i-1][j+1])
					if(s[i][j]>s[i+1][j-1]||s[i][j]>s[i+1][j]||s[i][j]>s[i+1][j+1])
						if(s[i][j]<=s[i][j+1]&&s[i][j]<=s[i][j-1])
							ans=min(ans,s[i][j]*2);
				if(s[i][j]>s[i-1][j+1]||s[i][j]>s[i][j+1]||s[i][j]>s[i+1][j+1])
					if(s[i][j]>s[i-1][j-1]||s[i][j]>s[i][j-1]||s[i][j]>s[i+1][j-1])
						if(s[i][j]<=s[i+1][j]&&s[i][j]<=s[i-1][j])
							ans=min(ans,s[i][j]*2);
				if(s[i][j]==s[i][j-1]&&s[i][j]<=s[i+1][j]&&s[i][j]<=s[i+1][j-1]&&s[i][j]<=s[i-1][j]&&s[i][j]<=s[i-1][j-1])ans=min(ans,s[i][j]*2+1);
				if(s[i][j]==s[i+1][j-1]&&s[i][j]<=s[i][j-1]&&s[i][j]<=s[i+1][j])ans=min(ans,s[i][j]*2+1);
				if(s[i][j]==s[i+1][j]&&s[i][j]<=s[i][j-1]&&s[i][j]<=s[i+1][j-1]&&s[i][j]<=s[i][j+1]&&s[i][j]<=s[i+1][j+1])ans=min(ans,s[i][j]*2+1);
				if(s[i][j]==s[i+1][j+1]&&s[i][j]<=s[i][j+1]&&s[i][j]<=s[i+1][j])ans=min(ans,s[i][j]*2+1);
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

上一题