Crazy Search

链接:http://acm.hust.edu.cn/vjudge/problem/17714/origin

题目:Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given text. Such number could be the number of different substrings of a given size that exist in the text. As you soon will discover, you really need the help of a computer and a good algorithm to solve such a puzzle.
Your task is to write a program that given the size, N, of the substring, the number of different characters that may occur in the text, NC, and the text itself, determines the number of different substrings of size N that appear in the text.

As an example, consider N=3, NC=4 and the text "daababac". The different substrings of size 3 that can be found in this text are: "daa"; "aab"; "aba"; "bab"; "bac". Therefore, the answer should be 5.

题意:有一个字符串,里面有nc种字符,问长度为n的连续字串共有多少种。

分析:字符串的数据结构除了kmp都是新学的,当时推荐用字符串哈希去做,现在想来气质这道题用字典树也是可以的,不过不知道会不会超时。。。在这道题里,把字符串变成nc进制的大数字,这样每个子串会有一个相应的值作为代号(预处理一个nc的n次幂,计算经常用到),不同字串的代号绝对不同。只要记录代号有几个就行了。我一开始用set记录的,结果超时了。。。。下次记得能用布尔数组标记就用bool来标记吧。。。

题解:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <cmath>
#include <cctype>
#include <cfloat>
#include <climits>
#include <complex>
#include <deque>
#include <list>
#include <set>
#include <utility>
#define rt return
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
#define ull unsigned long long
#define detie ios_base::sync_with_stdio(false);cin.tie(false);cout.tie(false)
#define pii pair<int,int>
#define lowbit(x) x&(-x)
using namespace std;
#define maxi 0x3f3f3f3f
#define MAX 1000100

int c[150];
bool  v[16000010];
char s[MAX];
int quickpow(int x, int n)
{
	int ans = 1;
	while (n)
	{
		if (n & 1)ans *= x;
		n /= 2;
		x *= x;
	}
	rt ans;
}

int main()
{
	//fr;
	detie;
	int n, nc;
	scanf("%d %d", &n, &nc);
	scanf("%s", s);
	int len = strlen(s);
	for (int i = 0, j = 0; i < len&&j < nc; i++)
		if (!c[s[i]])c[s[i]] = j++;
	int num = 0;
	int t = quickpow(nc, n - 1);
	for (int i = 0; i < n; i++)
		num = num*nc + c[s[i]];
	v[num] = true;
	int ans = 1;
	for (int i = 0; i + n < len; i++)
	{
		num = (num - c[s[i]] * t)*nc + c[s[i + n]];
		if (!v[num]){
			v[num] = true;
			ans++;
		}
	}
	printf("%d\n", ans);
	rt 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值