zoukankan      html  css  js  c++  java
  • P1228 地毯填补问题(分治)

    P1228 地毯填补问题(分治)

    题目描述

    相传在一个古老的阿拉伯国家里,有一座宫殿。宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站立的地方外的所有地方盖上,美丽漂亮聪慧的公主就是他的人了。公主这一个方格不能用地毯盖住,毯子的形状有所规定,只能有四种选择(如图4-l):

    并且每一方格只能用一层地毯,迷宫的大小为(2k)^2的方形。当然,也不能让公主无限制的在那儿等,对吧?由于你使用的是计算机,所以实现时间为1s。

    输入输出格式

    输入格式:

    输入文件共2行。

    第一行:k,即给定被填补迷宫的大小为2^k(0<k≤10);

    第二行:x y,即给出公主所在方格的坐标(x为行坐标,y为列坐标),x和y之间有一个空格隔开。

    输出格式:

    将迷宫填补完整的方案:每一补(行)为x y c (x,y为毯子拐角的行坐标和列坐标,c为使用毯子的形状,具体见上面的图1,毯子形状分别用1、2、3、4表示,x、y、c之间用一个空格隔开)。

    输入输出样例

    输入样例#1: 复制
    3                          
    3 3   
    输出样例#1: 复制
    5 5 1
    2 2 4
    1 1 4
    1 4 3
    4 1 2
    4 4 1
    2 7 3
    1 5 4
    1 8 3
    3 6 3
    4 8 1
    7 2 2
    5 1 4
    6 3 2
    8 1 2
    8 4 1
    7 7 1
    6 6 1
    5 8 3
    8 5 2
    8 8 1
    

    说明

    事实上感觉四个的形状分别是这样(仅供参考,如果有问题联系icy)

    spj报错:

    1:c 越界

    2:x,y 越界

    3:mp[x][y] 已被占用

    4:mp[x][y] 从未被使用

    题解:

    初看这个问题,似乎无从下手,于是我们可以先考虑最简单的情况,既n = 2时

    0 0 0 1 这时,无论公主在哪个格子,我们都可以用一块毯子填满

    继续考虑n = 4的情况

    我们已经知道了解决2 * 2的格子中有一个障碍的情况如何解决,因此我们可以尝试构造这种情况

    首先,显然可以将4 4的盘面划分成4个2 2的小盘面,其中一块已经存在一个障碍了

    而我们只需在正中间的2 * 2方格中放入一块地毯,就可以使所有小盘面都有一个障碍

    于是,n = 4的情况就解决了

    我们可以将n = 4时的解法可以推广到一般情况,既当n = 2 k时,我们均可以将问题划分为4个n = 2 k – 1的子问题,然后分治解决即可。

    下面附上代码(算法:分治):

     1 #include<cstdio>
     2 typedef long long ll;
     3 ll x,y,len; int k;
     4 ll fun(int k)
     5 {
     6     ll sum=1;
     7     for(int i=1;i<=k;++i) sum*=2;
     8     return sum;
     9 }
    10 void solve(ll x,ll y,ll a,ll b,ll l)
    11 {
    12     if(l==1) return;
    13     if(x-a<=l/2-1 && y-b<=l/2-1)
    14     {
    15         printf("%lld %lld 1
    ",a+l/2,b+l/2);
    16         solve(x,y,a,b,l/2);
    17         solve(a+l/2-1,b+l/2,a,b+l/2,l/2);
    18         solve(a+l/2,b+l/2-1,a+l/2,b,l/2);
    19         solve(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
    20     }
    21     else if(x-a<=l/2-1 && y-b>l/2-1)
    22     {
    23         printf("%lld %lld 2
    ",a+l/2,b+l/2-1);
    24         solve(a+l/2-1,b+l/2-1,a,b,l/2);
    25         solve(x,y,a,b+l/2,l/2);
    26         solve(a+l/2,b+l/2-1,a+l/2,b,l/2);
    27         solve(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
    28     }
    29     else if(x-a>l/2-1 && y-b<=l/2-1)
    30     {
    31         printf("%lld %lld 3
    ",a+l/2-1,b+l/2);
    32         solve(a+l/2-1,b+l/2-1,a,b,l/2);
    33         solve(a+l/2-1,b+l/2,a,b+l/2,l/2);
    34         solve(x,y,a+l/2,b,l/2);
    35         solve(a+l/2,b+l/2,a+l/2,b+l/2,l/2);
    36     }
    37     else
    38     {
    39         printf("%lld %lld 4
    ",a+l/2-1,b+l/2-1);
    40         solve(a+l/2-1,b+l/2-1,a,b,l/2);
    41         solve(a+l/2-1,b+l/2,a,b+l/2,l/2);
    42         solve(a+l/2,b+l/2-1,a+l/2,b,l/2);
    43         solve(x,y,a+l/2,b+l/2,l/2);
    44     }
    45 }
    46 int main()
    47 {
    48     scanf("%d %lld %lld",&k,&x,&y);
    49     len=fun(k);
    50     solve(x,y,1,1,len);
    51     return 0;
    52 }
  • 相关阅读:
    均值回归理论,均值回归法则是指万物最终都将回归于其长期的均值
    文本框仅允许输入大于0的正整数
    Angularjs接收服务端的布尔值
    Ajax POST单个对象或多个对象至API
    ASP.NET MVC程序重构
    查询数据库创建时间
    查询MS SQL的版本号
    获取Data和Log默认路径
    快速查找对象
    表关联使用INNER JOIN实现更新功能
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/8185370.html
Copyright © 2011-2022 走看看