HDU 5510 Bazinga(技巧 + 字符串哈希)
2015-11-02 17:52
337 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510
题意:
依次给出n个串, 找出下标最大且不能包含前面所有的串的串(即前面所有的串都是这个串的子串)。
分析:
这道题我一开始的想法是AC自动机, 但是数据太大就MLE;就换了种思路。 其实可以发现, 如果a是b的子串,b是c的子串, 那么就不虚要比较a和c就能得到a也是c子串。 所以我们只需把所有互不包含的串的下标存起来, 来一个新串就和他们比较, 把是新串的子串的串清除出去即可了。这样一直进行下去最后一个不能包含前面的串的新串就是答案。 比较一个串是否包含另一串,快速的方法就是字符串哈希。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef unsigned long long ULL;
#define SEED 1000000007
const int maxn = 2010;
const int N = 505;
int p[maxn], pos;
char s
[maxn];
ULL k[maxn], Hash[maxn], hash_[maxn];
void init()
{
k[0] = 1;
for(int i = 1; i < maxn; i++)
k[i] = k[i-1] * SEED;
}
bool Pa(int len)
{
int id = p[pos-1];
int L = strlen(s[id]);
hash_[L] = 0;
for(int i = L-1; i >= 0; i--)
hash_[i] = hash_[i+1] * SEED + s[id][i]-'a'+1;
for(int i = 0; i <=len-L; i++)
{
if(hash_[0] == Hash[i]-Hash[i+L]*k[L])
return true;
}
return false;
}
int main()
{
int T, n, len, ans;
scanf("%d", &T);
init();
for(int cas = 1; cas <= T; cas++)
{
scanf("%d", &n);
pos = 0;
ans = -1;
for(int i = 1; i <= n; i++)
{
scanf("%s", s[i]);
len = strlen(s[i]);
Hash[len] = 0;
for(int j = len-1; j >= 0; j--)
Hash[j] = Hash[j+1] * SEED + s[i][j]-'a'+1;
while(pos)
{
if(Pa(len))
pos--;
else
{
ans = i;
break;
}
}
p[pos++] = i;
}
printf("Case #%d: %d\n", cas, ans);
}
return 0;
}
题意:
依次给出n个串, 找出下标最大且不能包含前面所有的串的串(即前面所有的串都是这个串的子串)。
分析:
这道题我一开始的想法是AC自动机, 但是数据太大就MLE;就换了种思路。 其实可以发现, 如果a是b的子串,b是c的子串, 那么就不虚要比较a和c就能得到a也是c子串。 所以我们只需把所有互不包含的串的下标存起来, 来一个新串就和他们比较, 把是新串的子串的串清除出去即可了。这样一直进行下去最后一个不能包含前面的串的新串就是答案。 比较一个串是否包含另一串,快速的方法就是字符串哈希。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef unsigned long long ULL;
#define SEED 1000000007
const int maxn = 2010;
const int N = 505;
int p[maxn], pos;
char s
[maxn];
ULL k[maxn], Hash[maxn], hash_[maxn];
void init()
{
k[0] = 1;
for(int i = 1; i < maxn; i++)
k[i] = k[i-1] * SEED;
}
bool Pa(int len)
{
int id = p[pos-1];
int L = strlen(s[id]);
hash_[L] = 0;
for(int i = L-1; i >= 0; i--)
hash_[i] = hash_[i+1] * SEED + s[id][i]-'a'+1;
for(int i = 0; i <=len-L; i++)
{
if(hash_[0] == Hash[i]-Hash[i+L]*k[L])
return true;
}
return false;
}
int main()
{
int T, n, len, ans;
scanf("%d", &T);
init();
for(int cas = 1; cas <= T; cas++)
{
scanf("%d", &n);
pos = 0;
ans = -1;
for(int i = 1; i <= n; i++)
{
scanf("%s", s[i]);
len = strlen(s[i]);
Hash[len] = 0;
for(int j = len-1; j >= 0; j--)
Hash[j] = Hash[j+1] * SEED + s[i][j]-'a'+1;
while(pos)
{
if(Pa(len))
pos--;
else
{
ans = i;
break;
}
}
p[pos++] = i;
}
printf("Case #%d: %d\n", cas, ans);
}
return 0;
}
相关文章推荐
- hdoj 3339 In Action【最短路+01背包】
- Navicat远程无法连接mysql问题解决(附MAC上NavicatPremium11.1.8破解中文版下载链接)
- openstack i版常用命令
- ios 系统NavigationBar隐藏
- 关于HTTP请求体格式
- JAVA中HashMap和HashTable的区别
- RabbitMQ的使用
- 查找网站后台N种方法总结
- 我之见解字符串
- url中传递中文参数出现乱码的问题
- 黑马程序员——OC基础知识
- Quartz 任务调度(二)
- android四大组件之-Broadcast的使用、Content Provider的使用
- java(基础)学习第一步:安装jdk,配置环境变量
- Android 开发笔记
- android单向无限循环的轮播图效果。
- [Linux] - Docker制作nginx+php
- Apache Kafka源码分析 - PartitionStateMachine
- 修改归并排序实现逆序对计数
- maven 插件生成mybatis相关代码