洛谷p1228:经典分治
思路:将当前迷宫分为四个部分,判断公主在哪个部分,考虑当前迷宫的中心2*2矩形,即四个部分的四个角构成的矩形,用地毯覆盖除公主所在部分的另外三个方格,这样一来,四个部分都存在“公主”,即将原问题转化成了四个独立子问题,在对四个子问题同样处理继续转化,当分解到子问题为2*2矩形时,用地毯覆盖另外三个点,继续分解发现分解不了,回退,即ac该题
代码:
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fun(ll k)
{
ll sum=1;
for(ll i=1;i<=k;i++)
{
sum*=2;
}
return sum;
}//算出2^k;
void solve (ll x,ll y,ll a,ll b,ll len)//x,y为公主, a,b为当前考虑迷宫的左上角,即大问题
{ //a,b用来算出覆盖中心矩形的哪三个点,即用哪种地毯
//len表示迷宫大小
if(len==1)return ;//len为1时无法继续分解为四个小问题,返回
if(x-a<=len/2-1&&y-b<=len/2-1)//公主在左上
{
//左上开始逆时针处理
printf("%lld %lld 1\n",a+len/2,b+len/2);//覆盖的点也看做公主
solve(x,y,a,b,len/2);//zuo shang
solve(a+len/2-1,b+len/2,a,b+len/2,len/2);//zuoxia
solve(a+len/2,b+len/2,a+len/2,b+len/2,len/2);//youxia
solve(a+len/2,b+len/2-1,a+len/2,b,len/2);//youshang
}else
if(x-a<=len/2-1&&y-b>=len/2)//左下
{
//左上开始逆时针处理
printf("%lld %lld 2\n",a+len/2,b+len/2-1);//覆盖的点也看做公主
solve(a+len/2-1,b+len/2-1,a,b,len/2);
solve(x,y,a,b+len/2,len/2);
solve(a+len/2,b+len/2,a+len/2,b+len/2,len/2);
solve(a+len/2,b+len/2-1,a+len/2,b,len/2);
}else
if(x-a>=len/2&&y-b>=len/2)//右下
{
//左上开始逆时针处理
printf("%lld %lld 4\n",a+len/2-1,b+len/2-1);//覆盖的点也看做公主
solve(a+len/2-1,b+len/2-1,a,b,len/2);
solve(a+len/2-1,b+len/2,a,b+len/2,len/2);
solve(x,y,a+len/2,b+len/2,len/2);
solve(a+len/2,b+len/2-1,a+len/2,b,len/2);
}else if(x-a>=len/2&&y-b<=len/2-1)//右上
{
//左上开始逆时针处理
printf("%lld %lld 3\n",a+len/2-1,b+len/2);//覆盖的点也看做公主
solve(a+len/2-1,b+len/2-1,a,b,len/2);
solve(a+len/2-1,b+len/2,a,b+len/2,len/2);
solve(a+len/2,b+len/2,a+len/2,b+len/2,len/2);
solve(x,y,a+len/2,b,len/2);
}
}
int main ()
{
ll x,y,k;
scanf("%lld %lld %lld",&k,&x,&y);
ll sum=fun(k);
solve(x,y,1,1,sum);
return 0;
}