BUAA 更大公约数

题目链接

给一个n*m的矩阵, 删除里面的一行一列, 使得剩下的数的最大公约数最大。

一个格子(x,y), 先预处理出(1,1)到这个格子的内所有数的最大公约数, 同理处理出(1, m), (n, m), (n, 1), 然后枚举格子中的每一个数, 具体看代码。

#include<bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
const int maxn = 1080;
int a[maxn][maxn], b[maxn][maxn], c[maxn][maxn], d[maxn][maxn];
int init[maxn][maxn];
int gcd(int a, int b) {
    return b == 0?a:gcd(b, a%b);
}
int main()
{
    int n, m;
    while(cin>>n>>m) {
        for(int i = 1; i<=n; i++) {
            for(int j = 1; j<=m; j++)
                scanf("%d", &init[i][j]);
        }
        mem(a); mem(b); mem(c); mem(d);
        for(int i = 1; i<=n; i++) {
            for(int j = 1; j<=m; j++) {
                a[i][j] = gcd(a[i][j-1], a[i-1][j]);
                a[i][j] = gcd(a[i][j], init[i][j]);
            }
        }
        for(int i = 1; i<=n; i++) {
            for(int j = m; j>=1; j--) {
                b[i][j] = gcd(b[i][j+1], b[i-1][j]);
                b[i][j] = gcd(b[i][j], init[i][j]);
            }
        }
        for(int i = n; i>=1; i--) {
            for(int j = 1; j<=m; j++) {
                c[i][j] = gcd(c[i][j-1], c[i+1][j]);
                c[i][j] = gcd(c[i][j], init[i][j]);
            }
        }
        for(int i = n; i>=1; i--) {
            for(int j = m; j>=1; j--) {
                d[i][j] = gcd(d[i][j+1], d[i+1][j]);
                d[i][j] = gcd(d[i][j], init[i][j]);
            }
        }
        int ans = 0;
        for(int i = 1; i<=n; i++) {
            for(int j = 1; j<=m; j++) {
                int tmp1 = gcd(a[i-1][j-1], b[i-1][j+1]);
                int tmp2 = gcd(c[i+1][j-1], d[i+1][j+1]);
                ans = max(ans, gcd(tmp1, tmp2));
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yohaha/p/5063196.html