分治——地毯覆盖

题目来源


DBSDFZOJ[东北师大附中OJ]

(洛谷也有类似题目 但样例貌似有点问题)



题目描述


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

                                                

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




第一行:k,即给定被填补迷宫的大小为2k(0<k≤10);
第二行:x y,即给出公主所在方格的坐标(x为行坐标,y为列坐标),x和y之间有一个空格隔开。

输入文件共2行。


输出


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


样例输入


3 3 3



样例输出


4 4 4

2 2 1

1 1 1
1 3 2
3 1 3
3 3 4
2 6 2
1 5 1
1 7 2
3 5 2
3 7 4
6 2 3
5 1 1
5 3 3
7 1 3
7 3 4
6 6 4
5 5 4
5 7 2
7 5 3
7 7 4



解题思路


深搜分割 

将当前方块分割成四块 则其中有且只有一块中有格子已经被涂色 

在其他三块方块交汇处涂色(放置地毯)输出

继续分割 直至方块为2*2规格 输出 

返回上一层



样例解释


上图(样例)颜色填涂顺序:

红色

橙色

黄色
绿色
浅蓝
淡紫
深紫
湖蓝
蓝紫
粉色




代码实现(C++)

#include <cstdio> 
#include <iostream> 
using namespace std; 
int k,num=0,pp,qq; 
void search(int x,int y,int len,int xx,int yy); 
//x-当前方块左上点横坐标  y-当前方块左上点纵坐标
//len-当前方块边长
//xx-当前方块已涂色格子横坐标  yy-当前方块已涂色格子纵坐标
int main() 
{ 
   scanf("%d",&k);  k=(1<<k); 
   scanf("%d%d",&pp,&qq); 
   search(1,1,k,pp,qq); 
   return 0; 
} 
void search(int x,int y,int len,int xx,int yy) 
{ 
    if(len==2) 
    { 
        printf("%d %d ",x,y); 
        if(xx==x&&yy==y) 
            printf("4\n"); 
        else if(xx==x&&yy==y+1) 
            printf("3\n"); 
        else if(xx==x+1&&yy==y) 
            printf("2\n"); 
        else 
            printf("1\n");
//在当前2*2方块中 根据已涂色格子位置 填入适当的毯子 
        return ; 
    } 
    int w; 
    if(yy<y+len/2) 
    { 
        if(xx<x+len/2) 
            w=1; 
//当前方块已涂色格子在分割后左上位方块中
        else
            w=3; 
//当前方块已涂色格子在分割后左下位方块中
    } 
    else
    { 
        if(xx<x+len/2) 
            w=2; 
//当前方块已涂色格子在分割后右上位方块中
        else 
            w=4; 
//当前方块已涂色格子在分割后右下位方块中
    } 
    printf("%d %d %d\n",x+len/2-1,y+len/2-1,5-w); 
    if(w!=1) 
        search(x,y,len/2,x+len/2-1,y+len/2-1); 
    else
        search(x,y,len/2,xx,yy); 
    if(w!=2) 
        search(x,y+len/2,len/2,x+len/2-1,y+len/2); 
    else
        search(x,y+len/2,len/2,xx,yy); 
    if(w!=3) 
        search(x+len/2,y,len/2,x+len/2,y+len/2-1); 
    else
        search(x+len/2,y,len/2,xx,yy); 
    if(w!=4) 
        search(x+len/2,y+len/2,len/2,x+len/2,y+len/2); 
    else
        search(x+len/2,y+len/2,len/2,xx,yy); 
//如果此方块中有已涂色格子(即当前方块中已涂色格子位于此方块中) 则本次涂色后 此方块中已涂色格子是当前方块中的已涂色格子
//否则 此方块中已涂色格子为分割时位于四块方块交汇处的格子
    return ; 
}


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值