惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
MyScale Blog
MyScale Blog
雷峰网
雷峰网
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
V
V2EX
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
N
Netflix TechBlog - Medium
Vercel News
Vercel News
美团技术团队
人人都是产品经理
人人都是产品经理
The Cloudflare Blog

OhYee 博客

小鹏辅助驾驶测评|OhYee 博客 小鹏非支持手机开启自动解锁|OhYee 博客 使用函数计算实现 301 重定向|OhYee 博客 针对 HTML 内容使用 Ant Design 图片弹框|OhYee 博客 博客进程泄露及僵尸进程解决|OhYee 博客 蓝易云服务器体验|OhYee 博客 SSH 调起本地 VSCode|OhYee 博客 【2022 秋招内推】阿里云后端研发工程师|OhYee 博客 使用函数计算获取 IP 地址信息|OhYee 博客 正确获取客户端 IP/HTTP Header 也可能重复|OhYee 博客 评测 Oculus Quest2 及 BigScreen|OhYee 博客 NextJS 热重载保留状态|OhYee 博客 如何优雅地贴 gist 代码|OhYee 博客 Linux 精细化文件权限|OhYee 博客 VSCode 容器开发环境|OhYee 博客 Clash 的不兼容更新排查|OhYee 博客 Zeek 导出 PCAP|OhYee 博客 记一次 ssh 配置问题|OhYee 博客 Git Commit 规范化工具|OhYee 博客 谈谈《星之卡比-探索发现》|OhYee 博客 VSCode 快捷键绑定 Shell 命令|OhYee 博客 ASN.1 语法及 X.509 证书格式解析解析|OhYee 博客 腾讯企业邮箱忽略 MX 记录发信|OhYee 博客 Chrome/Edge 标签组插件|OhYee 博客 【应届内推】阿里云后端研发工程师|OhYee 博客 损坏的 Typecho 备份处理为 JSON|OhYee 博客 VS Code VIM 插件高效使用|OhYee 博客 SSH 正反向代理|OhYee 博客 Let's Encrypt 根证书过期引发的问题|OhYee 博客 OpenWRT 忽略内核依赖|OhYee 博客
AOJ 859.地毯填补问题|OhYee 博客
2017-05-08 · via OhYee 博客

题目

{% fold 点击显/隐题目 %}

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

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

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

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

3 3 33

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

{% endfold %}

题解

由于AOJ没有 Special Judge 因此下面的代码没有 AC


不管什么情况,显然

代码

{% fold 点击显/隐代码 %}```cpp 地毯填补问题 https://github.com/OhYee/sourcecode/tree/master/ACM 代码备份
//
#define debug
#include
//
/
#include
#include
#include
#include
using namespace std;

inline bool between(int l, int m, int r) { return l <= m && m <= r; }
//int ID = 0;

struct Point {
int x, y;
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
bool operator==(const Point &rhs) const { return x == rhs.x && y == rhs.y; }
};
struct Area {
int x1, x2, y1, y2;
//int id;
Area(int _x1 = 0, int _x2 = 0, int _y1 = 0, int _y2 = 0) {
init(_x1, _x2, _y1, _y2);
// printf("A %d %d %d %d id:%d\n", x1, x2, y1, y2, id);
}
Area(int t[4]) {
init(t[0], t[1], t[2], t[3]);
// printf("B %d %d %d %d id:%d\n", x1, x2, y1, y2, id);
}
Area(const Area &rhs) {
init(rhs.x1, rhs.x2, rhs.y1, rhs.y2);
// printf("C %d %d %d %d id:%d\n", x1, x2, y1, y2, id);
}
//~Area() { printf("del %d %d %d %d id:%d\n", x1, x2, y1, y2, id); }
Area operator=(const Area rhs) {
init(rhs.x1, rhs.x2, rhs.y1, rhs.y2);
// printf("D %d %d %d %d id:%d\n", x1, x2, y1, y2, id);
return *this;
}

void init(int _x1 = 0, int _x2 = 0, int _y1 = 0, int _y2 = 0) {
    x1 = min(_x1, _x2);
    x2 = max(_x1, _x2);
    y1 = min(_y1, _y2);
    y2 = max(_y1, _y2);
    //id = ID++;
}

inline bool In(const Point p) const {
    return between(x1, p.x, x2) && between(y1, p.y, y2);
}
Area divide(int k) const {
    int midx = (x1 + x2) / 2;
    int midy = (y1 + y2) / 2;
    int t[4] = {x1, x2, y1, y2};
    if (k == 1) {
        t[1] = midx;
        t[3] = midy;
    } else if (k == 2) {
        t[1] = midx;
        t[2] = midy + 1;
    } else if (k == 3) {
        t[0] = midx + 1;
        t[3] = midy;
    } else { // k == 4
        t[0] = midx + 1;
        t[2] = midy + 1;
    }
    Area area(t);
    return area;
}
//获取区域方位角坐标
Point GetPoint(int k) const {
    Point t;
    if (k == 1)
        t = Point(x1, y1);
    else if (k == 2)
        t = Point(x1, y2);
    else if (k == 3)
        t = Point(x2, y1);
    else //  k == 4
        t = Point(x2, y2);

    return t;
}

};
void show(const Point &p, int k/, int deep/) {
// for (int i = 0; i < deep; i++)
// printf(" ");
// printf("%d %d %d\n", p.x, p.y, k);
printf("%d %d %d\n", p.x, p.y, k);
}

//通过左上顶点和方向获取拐角
Point GetCorner(const Point &p, int k) {
Point t;
if (k == 1)
t = Point(p.x + 1, p.y + 1);
else if (k == 2)
t = Point(p.x + 1, p.y);
else if (k == 3)
t = Point(p.x, p.y + 1);
else // k == 4
t = Point(p.x, p.y);
return t;
}
int pow(int a, int n) {
if (n == 0)
return 1;
if (n == 1)
return a;
return pow(a, n / 2) * pow(a, n - n / 2);
}

void dfs(Area area, Point p/, int deep/) {
// getchar();
// for (int i = 0; i < deep; i++)
// printf(" ");
// printf("Area: x1=%d x2=%d y1=%d y2=%d id=%d Point: (%d,%d)\n", area.x1,
// area.x2, area.y1, area.y2, area.id, p.x, p.y);

//递归终点
if (area.x2 - area.x1 == 1) {
    for (int i = 1; i <= 4; i++) {
        if (area.GetPoint(i) == p)
            show(GetCorner(Point((area.x1 + area.x2) / 2, (area.y1 + area.y2) / 2), i), i/*, deep*/);
    }
    return;
}

Area t;
for (int i = 1; i <= 4; i++) {
    t = area.divide(i);
    // printf("t %d %d %d %d id:%d\n", t.x1, t.x2, t.y1, t.y2, t.id);
    if (t.In(p)) {
        dfs(t, p/*, deep + 1*/);
        show(
            GetCorner(
                Point((area.x1 + area.x2) / 2, (area.y1 + area.y2) / 2), i), i/*, deep*/);
    } else {
        dfs(t, t.GetPoint(5 - i)/*, deep + 1*/);
    }
}

}

int main() {
#ifdef debug
freopen("in.txt", "r", stdin);
int START = clock();
#endif
freopen("out.txt", "w", stdout);
cin.tie(0);
cin.sync_with_stdio(false);

int k, x, y;
while (scanf("%d%d%d", &k, &x, &y) != EOF) {
    Area area = Area(1, pow(2, k), 1, pow(2, k));
    Point point = Point(x, y);
    dfs(area, point/*, 0*/);
}

#ifdef debug
printf("Time:%.3fs.\n", double(clock() - START) / CLOCKS_PER_SEC);
#endif
return 0;
}

{% endfold %}