【AOJ 859】地毯填补问题(分治)

来源:互联网 发布:聪明坏处 知乎 编辑:程序博客网 时间:2024/06/11 04:22

地毯填补问题

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

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

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

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

Sample Input
OriginalTransformed
33 3

Sample Output
OriginalTransformed
5 5 12 2 41 1 41 4 34 1 24 4 12 7 31 5 41 8 33 6 34 8 17 2 25 1 46 3 28 1 28 4 17 7 16 6 15 8 38 5 28 8 1


思路:分治法,将整个方格一直切分直至每一块都为2*2方格。每四个1*1部分由一个地毯和另外一个地毯的三分之一组成,这个地毯放在由四个2*2中组成的没有地毯的三个相邻区域,于是每个部分都成了只有一个三分之一地毯的子问题。

代码:

#include<bits/stdc++.h>#define MAX 1000using namespace std;int Map[MAX+50][MAX+50];int nx,ny; /*黑块指公主站地和有地毯的位置*//*x方向向下,y方向向右*/int judge(int x,int y,int xx,int yy);               //(xx,yy)表示黑块位置 ! void Fen(int x1,int y1,int x2,int y2,int x,int y);  //分治函数!(x1,y1)表示左上角起点,(x2,y2)表示右下角终点,(x,y)表示黑块位置. int main(){    int i,k,x,y,end=1;    std::ios::sync_with_stdio(false);    cin>>k;    cin>>x>>y;    memset(Map,0,sizeof(Map));    Map[x][y]=1;    for(i=0;i<k;i++) end*=2;    Fen(1,1,end,end,x,y);    return 0;}  int judge(int xx,int yy,int x,int y){               //(x,y)表示黑块位置 !     if(xx>=x&&yy>=y)      return 1;    else if(xx>=x&&yy+1<=y) return 2;    else if(xx+1<=x&&yy>=y) return 3;    else                    return 4;}void Fen(int x1,int y1,int x2,int y2,int x,int y){  //(x1,y1)表示左上角起点,(x2,y2)表示右下角终点,(x,y)表示黑块位置.    if(x2==x1+1) {                                  //分治最小情况,2*2方格,进行如下讨论         if(Map[x1][y1]==Map[x2][y1]==Map[x1][y2]==Map[x2][y2]==1) return ;        int xx,yy,t;        if(Map[x1][y1])             t=1,xx=x1+1,yy=y1+1;        else if(Map[x1][y1+1])      t=2,xx=x1+1,yy=y1;        else if(Map[x1+1][y1])      t=3,xx=x1,yy=y1+1;        else if(Map[x1+1][y1+1])    t=4,xx=x1,yy=y1;         cout<<xx<<" "<<yy<<" "<<t<<" "<<endl;        Map[x1][y1]=Map[x1][y1+1]=Map[x1+1][y1]=Map[x1+1][y1+1]=1;        return ;    }    //分治     int xx=(x1+x2)/2,yy=(y1+y2)/2;    int k=judge(xx,yy,x,y);    //四种情况,画图!!!8*8     if(k==1){   //公主在左上正方形格中         cout<<xx+1<<" "<<yy+1<<" "<<"1"<<" "<<endl;        Map[xx+1][yy]=Map[xx+1][yy+1]=Map[xx][yy+1]=1;        Fen(x1,y1,xx,yy,x,y);           //公主         Fen(x1,yy+1,xx,y2,xx,yy+1);     //地毯         Fen(xx+1,y1,x2,yy,xx+1,yy);     //地毯         Fen(xx+1,yy+1,x2,y2,xx+1,yy+1); //地毯     }    else if(k==2){  //公主在右上正方形格中         cout<<xx+1<<" "<<yy<<" "<<"2"<<" "<<endl;        Map[xx][yy]=Map[xx+1][yy]=Map[xx+1][yy+1]=1;        Fen(x1,y1,xx,yy,xx,yy);        Fen(x1,yy+1,xx,y2,x,y);        Fen(xx+1,y1,x2,yy,xx+1,yy);        Fen(xx+1,yy+1,x2,y2,xx+1,yy+1);    }    else if(k==3){  //公主在左下正方形格中         cout<<xx<<" "<<yy+1<<" "<<"3"<<" "<<endl;        Map[xx][yy]=Map[xx][yy+1]=Map[xx+1][yy+1]=1;        Fen(x1,y1,xx,yy,xx,yy);        Fen(x1,yy+1,xx,y2,xx,yy+1);        Fen(xx+1,y1,x2,yy,x,y);        Fen(xx+1,yy+1,x2,y2,xx+1,yy+1);    }    else if(k==4){  //公主在右下正方形格中         cout<<xx<<" "<<yy<<" "<<"4"<<" "<<endl;        Map[xx][yy]=Map[xx][yy+1]=Map[xx+1][yy]=1;        Fen(x1,y1,xx,yy,xx,yy);        Fen(x1,yy+1,xx,y2,xx,yy+1);        Fen(xx+1,y1,x2,yy,xx+1,yy);        Fen(xx+1,yy+1,x2,y2,x,y);    }}


原创粉丝点击