棋盘覆盖问题


前言

个人小记


一、棋盘覆盖问题是什么?

假设有一个 2 n × 2 n 2^n \times 2^n 2n×2n 的棋盘,其中一个方格被移除(比如说是一个角落的方格)。现在有 L 形的骨牌,每个骨牌覆盖 3 个方格,要求用这些 L 形骨牌覆盖整个棋盘,且不能有重叠

二、代码

#include<stdio.h>
#include <stdlib.h>

int **init_board(int k)
{
    int **board=(int**)malloc(sizeof(int *)*k);
    for(int i=0;i<k;i++)
    {
        board[i]=(int *)malloc(sizeof(int)*k);
    }
    for(int i=0;i<k;i++)
    {
        for(int j=0;j<k;j++)
        {
            board[i][j]=0;
        }
    }
    return board;
}
int f=1;
void converboard(int sr,int sc,int dr,int dc,int size,int **board)
{
    if(size==1)return ;
    size/=2;
    int flg=f++;
    if(dr<sr+size&&dc<sc+size)converboard(sr,sc,dr,dc,size,board);
    else 
    {
        board[sr+size-1][sc+size-1]=flg;
        converboard(sr,sc,sr+size-1,sc+size-1,size,board);
    }
    if(dr<sr+size&&dc>=sc+size)converboard(sr,sc+size,dr,dc,size,board);
    else
    {
        board[sr+size-1][sc+size]=flg;
        converboard(sr,sc+size,sr+size-1,sc+size,size,board);
    }
    if(dr>=sr+size&&dc<sc+size)converboard(sr+size,sc,dr,dc,size,board);
    else
    {
        board[sr+size][sc+size-1]=flg;
        converboard(sr+size,sc,sr+size,sc+size-1,size,board);
    }
    if(dr>=sr+size&&dc>=sc+size)converboard(sr+size,sc+size,dr,dc,size,board);
    else
    {
        board[sr+size][sc+size]=flg;
        converboard(sr+size,sc+size,sr+size,sc+size,size,board);
    }
    return ;
}

void clear(int **board,int k)
{
    if(board==NULL)return ;
    for(int i=0;i<k;i++)
    {
        free(board[i]);
    }
    free(board);
    return ;
}

int main()
{
    int x,y,k;
    printf("请输入特殊棋盘的行大小2^k中的k:");
    scanf("%d",&k);
    k=1<<k;
    int **board=init_board(k);
    printf("请输入特殊方格的位置x y:");
    scanf("%d%d",&x,&y);
    board[x][y]=-1;
    converboard(0,0,x,y,k,board);
    for(int i=0;i<k;i++)
    {
        for(int j=0;j<k;j++)
        {
            printf("%3d",board[i][j]);
        }
        printf("\n");
    }

    clear(board,k);
    return 0;
}

三、运行结果

请输入特殊棋盘的行大小2^k中的k:3 
请输入特殊方格的位置x y:2 2
  3  3  4  4  8  8  9  9
  3  2  2  4  8  7  7  9
  5  2 -1  6 10 10  7 11
  5  5  6  6  1 10 11 11
 13 13 14  1  1 18 19 19
 13 12 14 14 18 18 17 19
 15 12 12 16 20 17 17 21
 15 15 16 16 20 20 21 21

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值