题解:AT_abc358_f [ABC358F] Easiest Maze

什么时候 ABC 也开始构造了……

Idea

先判断无解。

显然最少走 nn 步才能到终点,最多途径 n×mn\times m 个格子。

上图中红色为最短的路径,蓝色为稍微绕一点路的路径,不难看出,无论我们怎么绕,都得多走至少 22 个格子回到原来的最短路上。

红线是我们的最短路径,而蓝线是最长的。我们考虑从最短路上每次加 22 个点,最后可能加到 kk 个点。

因为最短路在最右边,我们只需往左加即可。如果加到最左边了,就启用下一行。

但是有可能 kknn 在模 22 的意义下不同余,这样无解。

但是有可能 nn 为奇数,这样会出现下面的情况:

这时上图的绿线是利用率最高的。不难看出,我们在倒数第二行与最后一行之间作了许多弯曲。

所以只需在代码里判断一下这种情况就解完了。

注意本题特殊的输出格式。

Code

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
char ans[205][205];
void sol(){
	k=k-n;
	int x=2,y=2*m;
	k/=2;
	while(k){
		ans[x][y-1]='.';
		ans[x+1][y-2]='.';
		ans[x+2][y-1]='.';
		ans[x+1][y]='-';
		y-=2;
		k--;
		if(y<=2){
			y=2*m;
			x+=4;
		}
		if(x>=2*n)break;
	}
	if(k==0)return;
	x=2*n;y=2;
	while(k){
		k--;
		ans[x-1][y]='.';
		ans[x][y+1]='.';
		ans[x-1][y+2]='.';
		ans[x-2][y+1]='|';
		y+=4;
	}
	return;
}
int main(){
	cin>>n>>m>>k;
	if(k<n){
		cout<<"No";
		return 0;
	}
	else if(k>n*m){
		cout<<"No";
		return 0;
	}
	else if(k%2!=n%2){
		cout<<"No";
		return 0;
	}
	cout<<"Yes\n";
	for(int i=1;i<=2*n+1;i++){
		for(int j=1;j<=2*m+1;j++){
			if(i==1||i==2*n+1){
				ans[i][j]='+';
				if(j==2*m){
					if(i==1)ans[i][j]='S';
					else ans[i][j]='G';
				}
			} 
			else if(i%2==0){
				if(j==1||j==2*m+1)ans[i][j]='+';
				else{
					if(j%2)ans[i][j]='|';
					else ans[i][j]='o';	
				}
			}
			else{
				if(j%2)ans[i][j]='+';
				else if(j==m*2)ans[i][j]='.';
				else ans[i][j]='-';
			}
		}
	}
	sol();
//	ans[n*2-1][m*2]='.';
	ans[n*2+1][m*2]='G';
	for(int i=1;i<=2*n+1;i++){
		for(int j=1;j<=2*m+1;j++){
			cout<<ans[i][j];
		};
		cout<<endl;
	}
	return 0;
}
posted @   Weslie_qwq  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示