给一个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; }