题目链接
题目描述
在一个无限的方格中,想要填一个数 n n n,其上下左右必须有 n − 1 , n − 2 , n − 3 , n − 4 n-1,n-2,n-3,n-4 n−1,n−2,n−3,n−4,小于 5 5 5的数填到 1 1 1为止即可, 1 1 1可以无限填。问构造方法
思路
从后往前的考虑,假如说最后的数字是 n n n,那么它四周的数字就是 n − a , n − b , n − c , n − d n-a,n-b,n-c,n-d n−a,n−b,n−c,n−d,同理递推到 n − d n-d n−d,其左边的数字就变成了 n − d − b n-d-b n−d−b,递推到 n − a n-a n−a,其下面的数字就是 n − a − c n-a-c n−a−c,考虑一个数字可以共用到其上下左右,就要这样构造,然后可以发现 a + c = b + d a+c=b+d a+c=b+d,那么就可以当作 a = 1 , b = 2 , c = 4 , d = 3 a =1,b=2,c=4,d=3 a=1,b=2,c=4,d=3,倒着跑一遍dfs即可。但是直接dfs会爆输出限制,需要类似于记忆化搜索一样,记录一下是否重复构造,如果不重复再进行构造。
代码
#include
using namespace std;
typedef pair<int, int> PII;
map<PII, int> g;
void dfs(int x, int y, int n) {
if(n <= 0) return;
if(g[{x, y + 1}] != n - 1) {
dfs(x, y + 1, n - 1);
}
if(g[{x - 1, y}] != n - 2) {
dfs(x - 1, y, n - 2);
}
if(g[{x + 1, y}] != n - 3) {
dfs(x + 1, y, n - 3);
}
if(g[{x, y - 1}] != n - 4) {
dfs(x, y - 1, n - 4);
}
g[{x, y}] = n;
printf("%d %d %d\n", x, y, n);
}
void solve() {
int n; cin >> n;
dfs(0, 0, n);
}
int main() {
// freopen("in.txt", "r", stdin);
solve();
return 0;
}