棋盘覆盖(分治)

棋盘覆盖(分治)

Description
在一个2k × 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的棋盘上除特殊方格以外的所有方格,L型骨牌不能旋转,且任何两个L型骨牌不得重叠覆盖。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬ ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

Input
第一行是一个T,表示案例数。对于每一个案例,有三个数K,X,Y分别表示在一个2^k * 2^K的棋盘中,在第X行第Y列有一个特殊方格。1 ≤ K ≤ 8‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

1 ≤ X, Y ≤ 2k‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

Output
输出这个被骨牌覆盖的棋盘,分别用a,b,c,d表示四种骨牌(分别用以下四种字符图形表示),特殊方格用*号表示。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

aa bb c   d
a   b cc dd

具体输出见sample Output‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

Sample Input
2
2 1 2
1 1 1‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

Sample Output
c*bb
ccdb
cddd
ccdd
*d
dd‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬

Author
陈渝林

分治思想
分治就是把一个大问题分解成几个小问题解决,再把小问题的解整合起来成为问题的解。
把2^k * 2^K 的棋盘分成四个2^k-1 * 2^K-1的小棋盘。
在特殊方块在的小棋盘外的三个棋盘交界处加上合适的骨牌,使它们也变成特殊棋盘。以此类推,每次分割都把一个问题变成四个小问题,直至棋盘规模为1。
8*8的特殊棋盘

#include<stdio.h>
#include<string.h>
#include<math.h>
int mapp[300][300];
void chessBoard(int r,int c,int x,int y,int s)///r:起始行 c:起始列
{
    int ss,n;
    if(s==1)
        return;
    ss=s/2;///切分棋盘
    ///判断中间的骨牌为什么型号
    if(x<r+ss&&y<c+ss) n=4;///特殊格在左上角
    else if(x>=r+ss&&y<c+ss) n=2;///左下角
    else if(x<r+ss&&y>=c+ss) n=3;///右上角
    else n=1;///右下角

    if(x<r+ss&&y<c+ss)///左上角
    {
        chessBoard(r,c,x,y,ss);
    }
    else
    {
        mapp[r+ss-1][c+ss-1]=n;///覆盖右下角
        chessBoard(r,c,r+ss-1,c+ss-1,ss);
    }

    if(x>=r+ss&&y<c+ss)///左下角
    {
        chessBoard(r+ss,c,x,y,ss);
    }
    else
    {
        mapp[r+ss][c+ss-1]=n;///覆盖右上角
        chessBoard(r+ss,c,r+ss,c+ss-1,ss);
    }

    if(x<r+ss&&y>=c+ss)///右上角
    {
        chessBoard(r,c+ss,x,y,ss);
    }
    else
    {
        mapp[r+ss-1][c+ss]=n;///覆盖左下角
        chessBoard(r,c+ss,r+ss-1,c+ss,ss);
    }

    if(x>=r+ss&&y>=c+ss)///右下角
    {
        chessBoard(r+ss,c+ss,x,y,ss);
    }
    else
    {
        mapp[r+ss][c+ss]=n;///覆盖左上角
        chessBoard(r+ss,c+ss,r+ss,c+ss,ss);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
//    cin>>t;
    while(t--)
    {
        memset(mapp,0,sizeof(mapp));
        int k,x,y;
        scanf("%d %d %d",&k,&x,&y);
       // cin>>k>>x>>y;
        int s=pow(2,k);
        chessBoard(1,1,x,y,s);
        int i,j;
        for(i=1;i<=s;i++)
        {
            for(j=1;j<=s;j++)
            {
                if(i==x&&j==y)
                    printf("*");
                    //cout<<"*";
                else if(mapp[i][j]==1)
                    printf("a");
                   // cout<<"a";
                else if(mapp[i][j]==2)
                    printf("b");
                    //cout<<"b";
                else if(mapp[i][j]==3)
                    printf("c");
                    //cout<<"c";
                else if(mapp[i][j]==4)
                    printf("d");
                    //cout<<"d";
            }
            printf("\n");
//            cout<<endl;
        }
    }
    return 0;
}

作业题,有错误欢迎指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值