如果想看原题网址的话请点击这里:地毯填补问题

原题:

题目描述
相传在一个古老的阿拉伯国家里,有一座宫殿。宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站立的地方外的所有地方盖上,美丽漂亮聪慧的公主就是他的人了。公主这一个方格不能用地毯盖住,毯子的形状有所规定,只能有四种选择(如图):
(此处图误见后处的图)
并且每一方格只能用一层地毯,迷宫的大小为 ^k * ^k的方形。当然,也不能让公主无限制的在那儿等,对吧?由于你使用的是计算机,所以实现时间为1s。 输入格式
输入文件共 行。 第一行:kk,即给定被填补迷宫的大小为 ^k * ^k
第二行:x,yx,y,即给出公主所在方格的坐标(xx 为行坐标,yy 为列坐标),xx 和 yy 之间有一个空格隔开。 输出格式
将迷宫填补完整的方案:每一补(行)为x\ y\ cx y c(x,yx,y 为毯子拐角的行坐标和列坐标, cc 为使用毯子的形状,具体见上面的图 ,毯子形状分别用 ,,,,,, 表示,x,y,cx,y,c 之间用一个空格隔开)。 输入输出样例
输入 # 复制 输出 # 复制 说明/提示
事实上感觉四个的形状分别是这样(仅供参考,如果有问题联系 icy)
图见原题
spj 报错: cc 越界
x,yx,y 越界
mp[x][y]mp[x][y] 已被占用
mp[x][y]mp[x][y] 从未被使用

首先在分析该题之前ROS先解释一下这里的行坐标和列坐标:

此处的行坐标表示的是第几行,而列坐标表示的是第几列;此处的坐标定义与我们平常使用的平面直角坐标系中的坐标前后表示意义正好相反,所以需要解释一下(一开始ROS就是因为没有看懂这点所以写出了一些前后矛盾的代码)

好的行坐标和列坐标的意义解释完了,现在开始分析题目:

先来解析题目构建算法,那么这道题我们看到被洛谷贴上了“分治”的标签所以一定要用分治的思想。

先来解析题目构建算法,我们一开始来看这道题就想一种最暴力的算法:可不可以尝试给每个位置都尝试能否铺上4种地毯中的一种然后用一个vis数组来储存是否被访问过,如果其中出现了一块四种地毯都铺不了的位置时我们则回溯到上一状态呢?然而经过大概分析可以得知这一算法是肯定不行的,就单单给每个位置都访问一遍并且假设从一开始到最后永不回溯且每次地毯都恰好正确就需要2^2k次访问,但是这是不可能的,所以这种暴力dfs的做法就算是最好的情况下才会过但这种情况出现的可能性为0(除非有人无聊到专门做一个为了给这种做法的人得分的数据……)。所以这种暴力dfs的算法直接pass

那么我们在分析之后将问题简化:如果我们面对的问题是对于一个有四个格的正方形方块,我们知道公主站在其中一个格子上那么我们如何铺地毯呢?这显然是一个很简单的问题:把地毯铺在剩下三个剩余空间的地板上就可以了。(①)

我们的算法就是从这种思想(①)入手的。

没错这种想法看似很简单但是我们却可以从这种简单的思想中寻找我们需要的分治算法思想。

那么如果我们我们想象公主站在一个有2^k * 2^k个地板的方形上,那么我们可以将这个大的方形想象成4个大块,而公主则想象站在四个大块的其中一个上,那么我们的问题就变成了(①)中的问题,只需要把地毯铺在剩余3块大块上就可以了。那么我们就做完了。(②)

那么我们该把这个我们假想的这三块地毯铺在哪里呢?(③)

就铺在这一个方形的中间4个小地板的3个大块所对应的小地板上。(④)

然后我们对于那个有公主站着的大块我们再“把视角拉近”,把这一个大块分成4个小块。然后进行(②)(③)(④)的操作。

这就是分治的思想,即将问题一步步分解成小问题从而对分解出来的小问题求解最终就求出了想要的整体解。

其实对于(①)我们还可以有另一种解释,那就是我们可以将这四个大块的状态(公主是否站在上面)压缩到最中间的4个小方块上,所以我们就可以理所当然的将地毯铺在最中间的4的块中的3个上了。

那么下面是代码实现:

(说实话ROS算法思想其实早就懂了但是代码一直不会实现今天才把代码写完)

 #include<bits/stdc++.h>
using namespace std;
int k,x,y;
void dfs(int a,int b,int c,int e,int f);
int ksm(int x,int y);
int main(){
scanf("%d%d%d",&k,&x,&y);
dfs(x,y,k,,);
return ;
}
int ksm(int x,int y){
if(x==||x==) return x;
if(y==) return ;
if(y==) return x;
int tmp=ksm(x,y/);
if(y&){
return tmp*tmp*x;
}
return tmp*tmp;
}
void dfs(int a,int b,int c,int e,int f){
if(c==) return ;
int tmp=ksm(,c-);
if(a<=e+tmp-){
if(b<=f+tmp-){
printf("%d %d 1\n",e+tmp,f+tmp);
dfs(e+tmp,f+tmp,c-,e+tmp,f+tmp);
dfs(e+tmp,f+tmp-,c-,e+tmp,f);
dfs(e+tmp-,f+tmp,c-,e,f+tmp);
if(c>=) dfs(a,b,c-,e,f);
return ;
}
else{
printf("%d %d 2\n",e+tmp,f+tmp-);
dfs(e+tmp,f+tmp-,c-,e+tmp,f);
dfs(e+tmp,f+tmp,c-,e+tmp,f+tmp);
dfs(e+tmp-,f+tmp-,c-,e,f);
if(c>=) dfs(a,b,c-,e,f+tmp);
return ;
}
}
if(a>e+tmp-){
if(b>f+tmp-){
printf("%d %d 4\n",e+tmp-,f+tmp-);
dfs(e+tmp-,f+tmp-,c-,e,f);
dfs(e+tmp-,f+tmp,c-,e,f+tmp);
dfs(e+tmp,f+tmp-,c-,e+tmp,f);
if(c>=) dfs(a,b,c-,e+tmp,f+tmp);
return ;
}
else{
printf("%d %d 3\n",e+tmp-,f+tmp);
dfs(e+tmp-,f+tmp,c-,e,f+tmp);
dfs(e+tmp-,f+tmp-,c-,e,f);
dfs(e+tmp,f+tmp,c-,e+tmp,f+tmp);
if(c>=) dfs(a,b,c-,e+tmp,f);
return ;
}
}
return ;
}

由于ROS原来正是因为有一些困惑再加上ROS及其讨厌看题解(ROS认为这会影响到人的自主思维)而导致不会代码实现所以ROS把我当时的困惑说出来并进行解答:

1.

Q:如何实现我在搜索哪一个“大块”?

A:对于这一问题,ROS一开始真的不知道怎么表示。但后来ROS发现有于我们进行分治的思想所以我们可以知道我们这一次所进行搜索的正方形块边长是多少,所以我们可以通过一个块的坐标和正方形边长就可以得到我们在搜索的这个大块的具体坐标范围了。

2.

Q:有没有可能会出现最终有的地板没有相应的可以铺的地毯的情况?

A:这是不可能的。因为我们已经得知方形的边长为2^k所以一步步分下去(每一次分成4个等大的小块)一定是可以恰好有唯一情况分完的。

最后总结:分治就是把一个整体的大问题分成一个个可以解决的小问题然后解决小问题的过程。这种思想和递归类似,而与递归不同的是递归通常还是长时间消耗的代名词,而分治则通常不会消耗过长时间(以为没有调用自身的过程而把问题分解了)

浅谈分治 —— 洛谷P1228 地毯填补问题 题解的更多相关文章

  1. [洛谷P1228]地毯填补问题 题解(分治)

    Description 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站立的地方外的 ...

  2. 洛谷P1228 地毯填补问题

    P1228 地毯填补问题 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站 ...

  3. 浅谈SPFA——洛谷P1576 最小花费 题解

    想找原题请点击这里:传送门 原题: 题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少 ...

  4. P1228 地毯填补问题(分治)

    P1228 地毯填补问题(分治) 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将 ...

  5. 洛谷P1783 海滩防御 分析+题解代码

    洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...

  6. 洛谷P4047 [JSOI2010]部落划分题解

    洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...

  7. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  8. 洛谷10月月赛II题解

    [咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...

  9. [NOIP提高&洛谷P1024]一元三次方程求解 题解(二分答案)

    [NOIP提高&洛谷P1024]一元三次方程求解 Description 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约 ...

随机推荐

  1. MongoDB的安装问题

    Mongo的安装与启动: npm install mongodb -g MongoDB高性能.开源.无模式的文档型数据库,它基于分布式文件存储.介于关系数据库和非关系数据库之间的一种产品.其最大特点: ...

  2. 162.扩展User模型-使用Proxy模型

    扩展用户模型: Django内置的User模型虽然已经足够强大了,但是有时候还是不能满足我们的需求,比如在验证用户登录的时候,它用的是用户名作为验证,而我们有时候需要通过手机号码或者是邮箱进行验证,还 ...

  3. JavaSwing开发简单的银行管理系统 附源码

    开发环境: Windows操作系统开发工具: MyEclipse/Eclipse+Jdk+mysql数据库 运行效果图:

  4. app点击底部菜单切换标题

    <!DOCTYPE HTML><html><head> <meta charset="utf-8"> <meta name=& ...

  5. 全面了解 Java 原子变量类

    目录   一.原子变量类简介  二.基本类型  三.引用类型  四.数组类型  五.属性更新器类型  参考资料

  6. react 和 vue 的优缺点总结

    React推广了Virtual DOM并创造了新的语法——JSX,JSX允许开发者在JavaScript中书写HTML Vue使用模板系统而不是JSX,但能对现有应用的升级更加容易,这是因为模板用的就 ...

  7. Codeforces Round #601 (Div. 2) E1 Send Boxes to Alice (Easy Version)

    #include <bits/stdc++.h> using namespace std; typedef long long ll; ; int a[N]; int n; bool pr ...

  8. 中国城市区号脚本-mysql

    中国城市区号 300个. SET NAMES utf8mb4; ; DROP TABLE IF EXISTS `citycode`; CREATE TABLE `citycode` ( `codeId ...

  9. java多线程技术

    如何实现线程 首先实现线程的两个方法:1.继承thread:2.实现接口Runnable类: 这边我就说一下第二种,因此第二种在开发中使用的比较多一些,能避免继承还是少避免继承. RunnableDe ...

  10. hyper-v 80070057

    微软官网搜索MediaCreation tool进行升级.