C0201 方格GCD 题解

发现数据量较小,这里直接枚举左上角的所有因数,然后对每个因数来 check 一下有没有路径到达右下角,用的是存在性 dp

#include <bits/stdc++.h>
#include <cstdio>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair <int, int>

void solve () {
    int n, m; cin >> n >> m;
    vector < vector <int> > mp(n+1, vector <int> (m+1));
    for (int i = 1;i <= n;i++) 
        for (int j = 1;j <= m;j++) 
            cin >> mp[i][j]; 
    vector <int> use;
    for (int i = 1;i * i <= mp[1][1];i++) {
        if (!(mp[1][1]%i)) use.push_back(i);
        if (i*i != mp[1][1] && !(mp[1][1]%i)) use.push_back(mp[1][1]/i);
    }
    sort(use.begin(), use.end(), 
         [&](auto a, auto b) -> bool { return a > b; });
    auto check = [&](int target) -> bool {
        vector < vector <bool> > dp(n+1, vector <bool> (m+1));
        dp[1][1] = 1;
        for (int i = 1;i <= n;i++) 
            for (int j = 1;j <= m;j++) {
                if (i == 1 && j == 1) continue;
                if (!(mp[i][j]%target)) dp[i][j] = (dp[i-1][j] || dp[i][j-1]);
            }
        return dp[n][m]; 
    };
    for (auto tar : use) 
        if (check(tar)) {
            cout << tar << "\n";
            return;
        } 
}

int main () {
    freopen("square.in", "r", stdin);
    freopen("square.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}