大一acmer日常记录day14

洛谷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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值