2020 Multi-University Training Contest 4 L-Last Problem

题目链接
题目描述
在一个无限的方格中,想要填一个数 n n n,其上下左右必须有 n − 1 , n − 2 , n − 3 , n − 4 n-1,n-2,n-3,n-4 n1,n2,n3,n4,小于 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 na,nb,nc,nd,同理递推到 n − d n-d nd,其左边的数字就变成了 n − d − b n-d-b ndb,递推到 n − a n-a na,其下面的数字就是 n − a − c n-a-c nac,考虑一个数字可以共用到其上下左右,就要这样构造,然后可以发现 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会爆输出限制,需要类似于记忆化搜索一样,记录一下是否重复构造,如果不重复再进行构造。
2020 Multi-University Training Contest 4 L-Last Problem_第1张图片
代码

#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;
}

你可能感兴趣的:(比赛)