首页 > 代码库 > UVA 261 - The Window Property(字符串Hash)

UVA 261 - The Window Property(字符串Hash)

UVA 261 - The Window Property

题目链接

题意:这题题意挺绕的。。就是给定一个字符串长度n,扫描长度为k = [1,n],然后每次只能扫描连续k个字符的子串,要求所有扫描中,每次扫描中出现的不同字符串个数都不超过k + 1,那么这个字符串就是window property,如果不是的话,就还要找出下标最小的不符合的位置(就是n次扫描中找最小的)

思路:Hash大法好,长度才100,直接处理出hash,O(n^2)随便搞掉

代码:

#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;

typedef unsigned long long ull;

const int N = 105;
const ull x = 123;

char str[N];
ull H[N], Hp[N];
int n;

void gethash() {
    n = strlen(str);
    H[n] = 0;
    for (int i = n - 1; i >= 0; i--)
	H[i] = H[i + 1] * x + str[i] - 'a';
}

void solve() {
    int ans = n + 1;
    for (int l = 1; l <= n; l++) {
	set<ull> vis;
	int cnt = 0;
	for (int i = 0; i < n - l + 1; i++) {
	    ull tmp = H[i] - H[i + l] * Hp[l];
	    if (vis.find(tmp) == vis.end()) {
		vis.insert(tmp);
		cnt++;
	    }
	    if (cnt > l + 1) {
		ans = min(ans, i + l);
		break;
	    }
	}
    }
    if (ans != n + 1) printf("NO:%d\n", ans);
    else printf("YES\n");
}

int main() {
    Hp[0] = 1;
    for (int i = 1; i < N; i++)
	Hp[i] = Hp[i - 1] * x;
    while (gets(str) != NULL) {
	gethash();
	solve();
    }
    return 0;
}