题目链接
给一个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; }