《P1228 地毯填补问题》

发布于:2025-05-13 ⋅ 阅读:(18) ⋅ 点赞:(0)

题目描述

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

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

输入格式

输入文件共 2 行。

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

输出格式

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

输入输出样例

输入 #1复制

3                          
3 3   

输出 #1复制

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

代码实现:

#include<iostream>
using namespace std;
long long powerOfTwo, princessX, princessY;

void divideAndConquer(long long mazeStartX, long long mazeStartY, 
                      long long princessRow, long long princessCol, 
                      long long currentSizeExp) {
    if (currentSizeExp == 0) return;
    
    long long halfSize = 1 << (currentSizeExp - 1);
    long long middleX = mazeStartX + halfSize;
    long long middleY = mazeStartY + halfSize;
    
    if (princessRow < middleX && princessCol < middleY) {
        printf("%lld %lld %d\n", middleX, middleY, 1);
        divideAndConquer(mazeStartX, mazeStartY, princessRow, princessCol, currentSizeExp - 1);
        divideAndConquer(mazeStartX, middleY, middleX - 1, middleY, currentSizeExp - 1);
        divideAndConquer(middleX, mazeStartY, middleX, middleY - 1, currentSizeExp - 1);
        divideAndConquer(middleX, middleY, middleX, middleY, currentSizeExp - 1);
    }
    else if (princessRow < middleX && middleY <= princessCol) {
        printf("%lld %lld %d\n", middleX, middleY - 1, 2);
        divideAndConquer(mazeStartX, mazeStartY, middleX - 1, middleY - 1, currentSizeExp - 1);
        divideAndConquer(mazeStartX, middleY, princessRow, princessCol, currentSizeExp - 1);
        divideAndConquer(middleX, mazeStartY, middleX, middleY - 1, currentSizeExp - 1);
        divideAndConquer(middleX, middleY, middleX, middleY, currentSizeExp - 1);
    }
    else if (middleX <= princessRow && middleY > princessCol) {
        printf("%lld %lld %d\n", middleX - 1, middleY, 3);
        divideAndConquer(mazeStartX, mazeStartY, middleX - 1, middleY - 1, currentSizeExp - 1);
        divideAndConquer(mazeStartX, middleY, middleX - 1, middleY, currentSizeExp - 1);
        divideAndConquer(middleX, mazeStartY, princessRow, princessCol, currentSizeExp - 1);
        divideAndConquer(middleX, middleY, middleX, middleY, currentSizeExp - 1);
    }
    else {
        printf("%lld %lld %d\n", middleX - 1, middleY - 1, 4);
        divideAndConquer(mazeStartX, mazeStartY, middleX - 1, middleY - 1, currentSizeExp - 1);
        divideAndConquer(mazeStartX, middleY, middleX - 1, middleY, currentSizeExp - 1);
        divideAndConquer(middleX, mazeStartY, middleX, middleY - 1, currentSizeExp - 1);
        divideAndConquer(middleX, middleY, princessRow, princessCol, currentSizeExp - 1);
    }
}

int main() {
    cin >> powerOfTwo >> princessX >> princessY;
    divideAndConquer(1, 1, princessX, princessY, powerOfTwo);
    cin >> princessX; // 保留原代码中的这一行,可能用于调试
    return 0;
}

说明/提示

spj 报错代码解释:

  1. c 越界;
  2. x,y 越界;
  3. (x,y) 位置已被覆盖;
  4. (x,y) 位置从未被覆盖。

upd 2023.8.19:增加样例解释。

样例解释


网站公告

今日签到

点亮在社区的每一天
去签到