T265119 拯救公主--题解
题目描述
公主索菲亚被关在一个有大小一样的方格构成的四四方方的迷宫里面,索菲亚就站在其中一个方格子上,拯救方案是这样的:要用一些地砖把公主所在的方格子之外的格子都铺上,那么索菲亚就得救了。注意索菲亚所在的这一个格子不能用地砖铺上。地砖有如下四种规格(如图):
并且每个方格只能用一层地砖铺设,迷宫的大小是2^k * 2^k的方形。
输入格式
输入包含 2行。
第一行:k,即给定迷宫的大小是 2k*2k
第二行:x,y,即给出索菲亚所在方格的坐标(x 为行坐标,y为列坐标),x 和 yy之间以一个空格隔开。
输出格式
铺设砖块的方案:每一行是x y c(x,y 是砖块拐角的行坐标和列坐标,c是所用砖块的形状,具体见上面的图,砖块形状分别用 1,2,3,4 表示,x,y,cx,y,c 之间以空格隔开)。
题解
算法思想:
把迷宫从中间划分成四个部分,
若索菲亚所在方格在左上方时,在划分出用1号砖块填充,这样填充的砖块可以作为其他三个划分的缺口
若索菲亚所在方格在右上方时,在划分出用2号砖块填充,这样填充的砖块可以作为其他三个划分的缺口
若索菲亚所在方格在左下方时,在划分出用3号砖块填充,这样填充的砖块可以作为其他三个划分的缺口
若索菲亚所在方格在右下方时,在划分出用4号砖块填充,这样填充的砖块可以作为其他三个划分的缺口
然后对这四个部分重复上述操作直至不能进行划分及只有一个方格。
代码
#include<bits/stdc++.h>
using namespace std;
//从左上角(a,b)开始处理大小为n×n的迷宫,(x,y)为公主或者已覆盖的位置
void fun(int x,int y,int a,int b,int n){
if(n==1) return;
n=n/2;
if(x<=a+n-1&&y<=b+n-1){//公主或者已覆盖的位置在左上角,使用1号地毯
cout<<a+n<<" "<<a+n<<" "<<1<<endl;
fun(x,y,a,b,n);
fun(a+n-1,b+n,a,b+n,n);
fun(a+n,b+n-1,a+n,b,n);
fun(a+n,b+n,a+n,b+n,n);
}
else if(x<=a+n-1&&y>b+n-1){//公主或者已覆盖的位置在左上角,使用2号地毯
cout<<a+n<<" "<<b+n-1<<" "<<2<<endl;
fun(a+n-1,b+n-1,a,b,n);
fun(x,y,a,b+n,n);
fun(a+n,b+n-1,a+n,b,n);
fun(a+n,b+n,a+n,b+n,n);
}
else if(x>a+n-1&&y<=b+n-1){//公主或者已覆盖的位置在左上角,使用3号地毯
cout<<a+n-1<<" "<<b+n<<" "<<3<<endl;
fun(a+n-1,b+n-1,a,b,n);
fun(a+n-1,b+n,a,b+n,n);
fun(x,y,a+n,b,n);
fun(a+n,b+n,a+n,b+n,n);
}
else{//公主或者已覆盖的位置在左上角,使用4号地毯
cout<<a+n-1<<" "<<b+n-1<<" "<<4<<endl;
fun(a+n-1,b+n-1,a,b,n);
fun(a+n-1,b+n,a,b+n,n);
fun(a+n,b+n-1,a+n,b,n);
fun(x,y,a+n,b+n,n);
}
}
int main(){
int x,y,k;
cin>>k>>x>>y;
int n=1<<k;
fun(x,y,1,1,n);
}