分治:地毯填补问题
题目:P1228 地毯填补问题 - 洛谷
我们拿到⼀个矩阵后的策略就是:
- 先四等分;
- 找出缺⼝对⾯的区间,放上⼀块地毯;
- 递归处理四个⼦问题
根据题目的测试用例,可以测试出递归的顺序是:左上,左下,右上,右下。必须严格按照题目(隐含的)要求的顺序递归。
递归思路:首先要判断公主在哪一个区域?
四等分,如果公主在左上角,就在斜对面放一个毯子,从四等分的第一个起点开始递归。
四等分,如果公主在右下角,就在斜对面放一个毯子,从四等分的第一个起点开始递归。
剩下的同理。
涉及到坐标的计算,容易出错。可以用取值法,推算出正确的公式。
#include <iostream>using namespace std;int k, x, y;void dfs(int a, int b, int len, int x, int y)
{if (len == 1) return;len /= 2;if (x < a+len && y < b+len){//摆上一号地毯cout << a+len << " " << b+len << " " << 1 << endl;dfs(a, b, len, x, y);dfs(a, b+len, len, a+len-1, b+len);dfs(a+len, b, len, a+len, b+len-1);dfs(a+len, b+len, len, a+len, b+len); } else if (x >= a+len && y >= b+len){cout << a+len-1 << " " << b+len-1 << " " << 4 << endl;dfs(a, b, len, a+len-1, b+len-1);dfs(a, b+len, len, a+len-1, b+len);dfs(a+len, b, len, a+len, b+len-1);dfs(a+len, b+len, len, x, y);}else if(x >= a + len){cout << a + len - 1 << " " << b + len << " " << 3 << endl;dfs(a, b, len, a + len - 1, b + len - 1);dfs(a, b + len, len, a + len - 1, b + len);dfs(a+len, b, len, x, y);dfs(a+len, b+len, len, a+len, b+len);}else{cout << a + len << " " << b + len - 1 << " " << 2 << endl;dfs(a, b, len, a + len - 1, b + len - 1);dfs(a, b + len, len, x, y);dfs(a + len, b, len, a + len, b + len - 1);dfs(a + len, b + len, len, a + len, b + len);}} int main(){cin >> k >> x >> y;k = (1 << k);dfs(1, 1, k, x, y); return 0; }