[Ybt Advanced 2-2-5] Sub-square

Child square

Topic link: ybt efficient advanced 2-2-5

Topic

There are two square matrices, ask you the side length of the largest common sub-square matrix of these two rectangles.

Ideas

The matrix size of this question is only 50 505 0 look, we can directly search violence with hash.

First enumerate the lower right corner of the matrix selected by the two matrices, and then enumerate the matrix size in two.
Then take the maximum value.

Code

#include<cstdio>
#include<iostream>
#define mi1 97ull
#define mi2 103ull
#define ull unsigned long long

using namespace std;

int n, a[51][51], b[51][51], l, r, mid, ans, answer;
ull a_hash[51][51], b_hash[51][51], t1[51], t2[51];

bool compair(int sx, int sy, int tx, int ty, int mid) {
    
    //看两个矩阵是不是
	return (a_hash[sx][sy] - a_hash[sx][sy - mid] * t1[mid] - a_hash[sx - mid][sy] * t2[mid] + a_hash[sx - mid][sy - mid] * t1[mid] * t2[mid])
			==
			(b_hash[tx][ty] - b_hash[tx][ty - mid] * t1[mid] - b_hash[tx - mid][ty] * t2[mid] + b_hash[tx - mid][ty - mid] * t1[mid] * t2[mid])
			;
}

int main() {
    
    
	scanf("%d", &n);
	
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			scanf("%d", &a[i][j]);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			scanf("%d", &b[i][j]);
	
	t1[0] = t2[0] = 1ull;
	for (int i = 1; i <= n; i++) t1[i] = t1[i - 1] * mi1;
	for (int i = 1; i <= n; i++) t2[i] = t2[i - 1] * mi2;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
    
    
			a_hash[i][j] = a_hash[i][j - 1] * mi1 + a[i][j];
			b_hash[i][j] = b_hash[i][j - 1] * mi1 + b[i][j];
		}
	for (int i = 1; i <= n; i++)//得出两个矩阵的hash值
		for (int j = 1; j <= n; j++) {
    
    
			a_hash[i][j] += a_hash[i - 1][j] * mi2;
			b_hash[i][j] += b_hash[i - 1][j] * mi2;
		}
	
	for (int sx = 1; sx <= n; sx++)//枚举第一个矩阵右下角选哪里
		for (int sy = 1; sy <= n; sy++)
			for (int tx = 1; tx <= n; tx++)//枚举第二个矩阵右下角选哪里
				for (int ty = 1; ty <= n; ty++) {
    
    
					l = 0;
					r = min(min(sx, sy), min(tx, ty));
					ans = 0;
					while (l <= r) {
    
    //二分出最大的大小
						mid = (l + r) >> 1;
						if (compair(sx, sy, tx, ty, mid)) {
    
    
							ans = mid;
							l = mid + 1;
						}
						else r = mid - 1;
					}
					answer = max(answer, ans);
				} 
	
	printf("%d", answer);
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/112973228