URAL 1486Equal Squares

Posted abclzr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了URAL 1486Equal Squares相关的知识,希望对你有一定的参考价值。

题意:求给定字符矩阵中相同正方形矩阵的最大边长和这两个相同正方形的位置

第一次写字符串哈希,选两个不同的模数进行二维字符串哈希。

本来应该取模判断相等后再暴力扫矩阵来判断,但是我看到《Hash在信息学竞赛中的一类应用》中这么写道:

于是我还会再次判重吗?肯定不会!!!

于是这样写完后就调啊调,调出几个像没用unsigned long long这样的脑残错误后交上去就A了233

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
const int N = 503;
const ll p = 100007;
const int p1 = 1007;
const int p2 = 10007;

struct node {
	ll to; int nxt, x, y;
	node (ll _to = 0, int _nxt = 0, int _x = 0, int _y = 0) : to(_to), nxt(_nxt), x(_x), y(_y) {}
} E[N * N];

char s[N][N];
int point[p + 3], cnt, n, m;
ll hash1[N][N], hash[N][N], pow1[N], pow2[N];


void ins(ll from, ll to, int x, int y) {E[++cnt] = node(to, point[from], x, y); point[from] = cnt;}
int __(ll t) {
	ll f = t % p;
	for(int i = point[f]; i; i = E[i].nxt)
		if (E[i].to == t) return i;
	return 0;
}
bool _(int t) {
	memset(point, 0, sizeof(point)); cnt = 0;
	ll num;
	for(int i = 1; i <= n - t + 1; ++i)
		for(int j = 1; j <= m - t + 1; ++j) {
			num = hash[i + t - 1][j + t - 1] - hash[i + t - 1][j - 1] * pow1[t] - hash[i - 1][j + t - 1] * pow2[t] + hash[i - 1][j - 1] * pow1[t] * pow2[t];
			if (__(num)) return 1;
			ins(num % p, num, i, j);
		}
	return 0;
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);
	pow1[0] = 1; pow2[0] = 1;
	for(int i = 1; i < N; ++i) pow1[i] = pow1[i - 1] * p1, pow2[i] = pow2[i - 1] * p2;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j) {
			hash1[i][j] = hash1[i][j - 1] * p1 + (int) s[i][j];
			hash[i][j] = hash[i - 1][j] * p2 + hash1[i][j];
		}
	int left = 0, right = n == m ? n - 1 : min(n, m), mid;
	while (left < right) {
		mid = (left + right + 1) >> 1;
		if (_(mid)) left = mid;
		else right = mid - 1;
	}
	if (left == 0) puts("0");
	else {
		printf("%d\\n", left);
		memset(point, 0, sizeof(point)); cnt = 0;
		for(int i = 1; i <= n - left + 1; ++i)
			for(int j = 1; j <= m - left + 1; ++j) {
			ll num = hash[i + left - 1][j + left - 1] - hash[i + left - 1][j - 1] * pow1[left] - hash[i - 1][j + left - 1] * pow2[left] + hash[i - 1][j - 1] * pow1[left] * pow2[left];
			if (right = __(num)) {
				printf("%d %d\\n%d %d\\n", E[right].x, E[right].y, i, j);
				return 0;
			}
			ins(num % p, num, i, j);
		}
	}
	
	return 0;
}

神奇的哈希啊,我到现在都对你的时间复杂度感到迷茫~

以上是关于URAL 1486Equal Squares的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode:1486. 数组异或操作

CVRP基于matlab人工鱼群算法求解带容量的车辆路径规划问题含Matlab源码 1486期

模拟1486. 数组异或操作

bzoj1486[HNOI2009]最小圈

LeetCode1486. 数组异或操作(Java/c++ 暴力模拟)

LeetCode1486. 数组异或操作(Java/c++ 暴力模拟)