题目链接在这里
鉴于有的读者可能看不到题目,这里我就复述一下,具体就是如果构造一个n*m的矩阵,使得从某两个点之间的最短距离为k。障碍用’x’表示,路用’.'表示。
怎么做呢,可以看出来,这又是一个构造的题目。
在矩阵里面,我们可以感受一下,曲折的路线是最长的,所以我们就构造曲折的路径,然后在构造好的图上跑一下bfs求一下距离为k的点在哪,输出就好啦!
至于为什么曲折的路线就是最长的, 还有没有更长的构造方法呢,其实笔者也不知道,但是这样写确实AC了,所以笔者猜测,曲折的构造就是最长的构造方法。
不过我们不知道横着还是竖着构造更好,我们就两种构造方法都试一下,然后我们在路径比较长的那个图上跑bfs就好啦。
下面是代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
char G1[maxn][maxn],G2[maxn][maxn],G[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m,k;
struct node
{
int x;
int y;
int stp;
};
void bfs(int x,int y)
{
queue<node> q;
q.push({x,y,0});
vis[x][y] = 1;
while(!q.empty())
{
node now = q.front();
q.pop();
if(now.stp==k)
{
printf("%d %d\n",now.x,now.y);
return;
}
for(int i=0;i<4;i++)
{
int nx = now.x+dx[i];
int ny = now.y+dy[i];
if(nx>=1 && nx<=n && ny>=1 && ny<=m && !vis[nx][ny] && G[nx][ny]=='.')
{
vis[nx][ny] = 1;
int nstp = now.stp+1;
q.push({nx,ny,nstp});
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int cnt = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i%2)
{
G1[i][j] = '.';
cnt++;
}
else G1[i][j] = 'x';
}
}
for(int i=2;i<=n;i+=4)
{
G1[i][m] = '.';
cnt++;
}
for(int i=4;i<=n;i+=4)
{
G1[i][1] = '.';
cnt++;
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(i%2)
{
G2[j][i] = '.';
cnt--;
}
else G2[j][i] = 'x';
}
}
for(int i=2;i<=m;i+=4)
{
G2[n][i] = '.';
cnt--;
}
for(int i=4;i<=m;i+=4)
{
G2[1][i] = '.';
cnt--;
}
if(cnt<0)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
G[i][j] = G2[i][j];
}
}
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
G[i][j] = G1[i][j];
}
}
}
printf("1 1\n");
bfs(1,1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%c",G[i][j]);
}
printf("\n");
}
return 0;
}