zoukankan      html  css  js  c++  java
  • 【URAL 1486】Equal 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
    ", 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
    %d %d
    ", E[right].x, E[right].y, i, j);
    				return 0;
    			}
    			ins(num % p, num, i, j);
    		}
    	}
    	
    	return 0;
    }
    

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

  • 相关阅读:
    为什么MySQL死锁检测会严重降低TPS
    OneProxy FAQ 之proxy-user-list
    OneProxy主从延迟检测
    MySQL和OneSQL并行插入性能对比
    天下文章一大抄,你抄我来我抄它
    卖软件的尴尬
    死锁检测为什么耗时?
    28岁的我
    突然想把一生都奉献给MySQL
    如何确定编码风格?
  • 原文地址:https://www.cnblogs.com/abclzr/p/5515014.html
Copyright © 2011-2022 走看看