[分治] AOAPC2-ch8 棋盘覆盖问题

题目

棋盘覆盖问题。
有一个2k2k的方格棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图所示为L型牌的4种旋转方式。

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>

const int maxn = 3000;
int k, x, y, cnt = 0, ans[maxn][maxn];

int getnum(int x, int y, int d){
    int n = pow(2, d)/2;
    if (x < n && y < n) return 0;
    else if (x > n && y > n) return 3;
    else if (x < n && y > n) return 2;
    else if (x > n && y < n) return 1;
} 

void solve(int d, int x, int r, int c){

    cnt++;
    if (x != 0) ans[r+(int)pow(2,d-1)-1][c+(int)pow(2,d-1)-1] = cnt;
    if (x != 1) ans[r+(int)pow(2,d-1)-1][c+(int)pow(2,d-1)] = cnt;
    if (x != 2) ans[r+(int)pow(2,d-1)][c+(int)pow(2,d-1)-1] = cnt;
    if (x != 3) ans[r+(int)pow(2,d-1)][c+(int)pow(2,d-1)] = cnt;

    if (d > 1){
        if (x != 0) solve(d-1, 3, r, c);
        else solve(d-1, getnum(x, y, d-1), r, c);
        if (x != 1) solve(d-1, 2, r, c+pow(2, d-1));
        else solve(d-1, getnum(x, y, d-1), r, c+pow(2, d-1));
        if (x != 2) solve(d-1, 1, r+pow(2,d-1), c);
        else solve(d-1, getnum(x, y, d-1), r+pow(2,d-1), c);
        if (x != 3) solve(d-1, 0, r+pow(2,d-1), c+pow(2,d-1));
        else solve(d-1, getnum(x, y, d-1), r+pow(2,d-1), c+pow(2,d-1));
    }
}

int main(){
    scanf("%d%d%d", &k, &x, &y);
    solve(k, getnum(x,y,k), 0, 0);
    for (int i = 0; i<pow(2,k); i++){
        for (int j = 0; j<pow(2,k); j++)
            printf("%d ",ans[i][j]);
        printf("\n");
    }   

    return 0;
} 

其他话

  1. 代码好乱。。但是比较短还差不多。
  2. 这道题思路好想,但代码实现有点麻烦。这道题光想就想了一下午。。。
    3.大体思路:分治访问每个正方形的四个小方块,各自求解。对于有题给小方块的方块,必然有解。其它的,每个出一个还能凑三个,正好一个图形。所以就假设每个小方块都有个黑块,其中一个是题目给的,其它是靠向图中心的。
阅读更多
文章标签: 递归 分治
个人分类: 1.aoapc2ch8 内容题
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭