描述:以二維數組表示圖像,其值只有0、1兩種,尋找兩幅圖像中最大的相同部分
輸入:第一行輸入一個n,接下來的2n行輸入兩個n * n數組,尋找一個最大的m * m子區域,使得兩個數組在該子區域完全相同
輸出:輸出上述m
樣例輸入:
4
1 1 1 1
1 1 1 0
1 1 1 0
1 1 1 1
0 1 1 1
0 1 1 1
0 1 1 1
0 1 1 0
樣例輸出:
2
解釋:上述兩個4階數組中的一個2階子區域(第1、2行,第2、3列完全相同)
思路:首先通過異或運算求出表示相同部分的矩陣來。然後遍歷該數組(dp[i][j]表示以(i,j)點爲右下頂點的最大正方形的邊長),利用動態轉移方程:dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1(if異或出來的矩陣值爲1),其動態轉移方程的含義爲該點的左邊點、上邊點、左上點中最小邊長的正方形與該點纔可構成全爲1的正方形。
代碼實現:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,j,a[103][103],b[103][103],dp[103][103],x;
while(~scanf("%d",&n))
{
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
scanf("%d",&a[i][j]);
}
}
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
scanf("%d",&x);
b[i][j]=!(x^a[i][j]);//^爲異或運算符,同爲0,異爲1
}
}
memset(dp,0,sizeof(dp));
int max=0;
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
if(b[i][j]==1)
dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
if(dp[i][j]>max)max=dp[i][j];
}
}
printf("%d\n",max);
}
}