Description
有一个n×m的矩阵,元素是正整数。现在需要删除其某一行的所有元素和某一列的所有元素,使得剩下元素的最大公约数最大。(单个元素的最大公约数是自己)
Input
输入包含多组测试数据,以EOF结束。
每组数据第一行两个数n,m,表示矩阵的行数和列数。(2≤n,m≤1061)
下面n行,每行m个正整数,表示矩阵的元素。
Output
每组数据输出一行,表示最大的公约数。
Sample Input
2 3
3 1 6
4 2 18
2 2
1 2
3 4
Sample Output
3
4
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1061+10;
int a[maxn][maxn],d1[maxn][maxn],d2[maxn][maxn],d3[maxn][maxn],d4[maxn][maxn];
int main()
{
int n,m,i,j,ans,temp;
while(scanf("%d%d",&n,&m)!=EOF) {
ans=0;temp=0;
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
for(j=1;j<=m;j++) {
d1[0][j]=d2[0][j]=d3[0][j]=d4[0][j]=a[1][j];
d1[n+1][j]=d2[n+1][j]=d3[n+1][j]=d4[n+1][j]=a[n][j];
}
for(i=1;i<=n;i++) {
d1[i][0]=d2[i][0]=d3[i][0]=d4[i][0]=a[i][1];
d1[i][m+1]=d2[i][m+1]=d3[i][m+1]=d4[i][m+1]=a[i][m];
}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++)
d1[i][j]=__gcd(a[i][j],__gcd(d1[i-1][j],d1[i][j-1]));
}
for(i=1;i<=n;i++) {
for(j=m;j>=1;j--)
d2[i][j]=__gcd(a[i][j],__gcd(d2[i-1][j],d2[i][j+1]));
}
for(i=n;i>=1;i--) {
for(j=1;j<=m;j++)
d3[i][j]=__gcd(a[i][j],__gcd(d3[i+1][j],d3[i][j-1]));
}
for(i=n;i>=1;i--) {
for(j=m;j>=1;j--)
d4[i][j]=__gcd(a[i][j],__gcd(d4[i+1][j],d4[i][j+1]));
}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) {
temp=0;
if(i-1>=1&&j-1>=1) temp=d1[i-1][j-1];
if(i-1>=1&&j+1<=m) {
if(temp==0) temp=d2[i-1][j+1];
else temp=__gcd(temp,d2[i-1][j+1]);
}
if(i+1<=n&&j-1>=1) {
if(temp==0) temp=d3[i+1][j-1];
else temp=__gcd(temp,d3[i+1][j-1]);
}
if(i+1<=n&&j+1<=m) {
if(temp==0) temp=d4[i+1][j+1];
else temp=__gcd(temp,d4[i+1][j+1]);
}
ans=max(ans,temp);
}
}
printf("%d\n",ans);
}
return 0;
}
因为要删去一行一列,那么必然有一个交点(x,y),交线将平面分成4块,求出四个角的最大公约数即可。。。好题!!!!!!!!
(x-1,y-1)...(x-1,y+1)...(x+1,y-1)....(x+1,y+1)
本弱只ac了3题。。。。。。思维有待提高!!