1.hash表(哈希表)

codevs 2147 数星星--简单哈希

 时间限制: 3 s
 空间限制: 64000 KB
 题目等级 : 钻石 Diamond
题目描述 Description

小明是一名天文爱好者,他喜欢晚上看星星。这天,他从淘宝上买下来了一个高级望远镜。他十分开心,于是他晚上去操场上看星星。

不同的星星发出不同的光,他的望远镜可以计算出观测到的星星发出的光的数值W。小明当然想尽可能地多看到星星,于是他每看到一颗星星,就要看看他之前有没有看过这颗星星。但是他看的星星太多了,他根本数不过来,于是他让你帮忙。

输入描述 Input Description

共有两行,第一行只有一个整数,为小明观测到的星星的数量n。第二行有n个整数,每两个整数由一个空格隔开,分别为小明观测到每颗星星的光的数值W[1]-W[n]。

输出描述 Output Description

只有一行,这一行共有n个数字0或1。0表示对应的星星之前没有观测到,1表示对应的星星之前已经看过了。注意:数字之间没有空格!

样例输入 Sample Input

5

1 5 5 4 1

样例输出 Sample Output
00101
数据范围及提示 Data Size & Hint

样例是往往是骗人的,本题中

30%的数据,0<n≤5000。

20%的数据,-20000≤W≤20000。

60%的数据,0<n≤50000。

100%的数据,0<n≤500000;-2000000000≤W≤2000000000。

分类标签 Tags 点此展开

#include<iostream>
using namespace std;
#define mod 500009/*取>500000的最小质数即可*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
long long hash_table[mod*];
int n,w[mod];
int main()
{
memset(hash_table,-,sizeof(hash_table));
scanf("%d",&n);
for(int i=;i<=n;++i)
{
scanf("%d",&w[i]);
int k=abs(w[i])%mod;
bool flag=false;
while(hash_table[k]>=-)/*you shu le*/
{
if(hash_table[k]==w[i])
flag=true;
k++; }
hash_table[k]=w[i];
if(flag)
printf("");
else printf(""); }
return ;
}

2.KMP算法[POJ3461]乌力波

法国作家乔治·佩雷克(Georges Perec,1936-1982)曾经写过一本书,《敏感字母》(La disparition),全篇没有一个字母‘e’。他是乌力波小组(Oulipo Group)的一员。下面是他书中的一段话:

Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…

佩雷克很可能在下面的比赛中得到高分(当然,也有可能是低分)。在这个比赛中,人们被要求针对一个主题写出甚至是意味深长的文章,并且让一个给定的“单词”出现次数尽量少。我们的任务是给评委会编写一个程序来数单词出现了几次,用以得出参赛者最终的排名。参赛者经常会写一长串废话,例如500000个连续的‘T’。并且他们不用空格。

因此我们想要尽快找到一个单词出现的频数,即一个给定的字符串在文章中出现了几次。更加正式地,给出字母表{'A','B','C',...,'Z'}和两个仅有字母表中字母组成的有限字符串:单词W和文章T,找到W在T中出现的次数。这里“出现”意味着W中所有的连续字符都必须对应T中的连续字符。T中出现的两个W可能会部分重叠。

【输入格式】

输入包含多组数据。

输入文件的第一行有一个整数,代表数据组数。接下来是这些数据,以如下格式给出:

第一行是单词W,一个由{'A','B','C',...,'Z'}中字母组成的字符串,保证1<=|W|<=10000(|W|代表字符串W的长度)

第二行是文章T,一个由{'A','B','C',...,'Z'}中字母组成的字符串,保证|W|<=|T|<=1000000。

【输出格式】

对每组数据输出一行一个整数,即W在T中出现的次数。

【样例输入】

3

BAPC

BAPC

AZA

AZAZAZA

VERDI

AVERDXIVYERDIAN

样例输出

1

3

0

#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#define MT 1000100
#define MW 10100
char w[MW],t[MT];
int ans=;
int fail[MW];
void input()
{
memset(w,,sizeof(w));
memset(t,,sizeof(t));
memset(fail,,sizeof(fail));
scanf("%s%s",w,t);
}
void make_fail()
{
int k=;
int lenw=strlen(w);
fail[]=;//
for(int i=;i<=lenw;++i)//
{
while(k>&&w[i]!=w[k])
k=fail[k-];//
if(w[i]==w[k])
k++;
fail[i]=k;
}
}
void kmp()
{
int lent=strlen(t);//mu
int lenw=strlen(w);
int k=;
for(int i=;i<=lent;++i)
{
while(k>&&t[i]!=w[k])
k=fail[k-];//
if(t[i]==w[k])
{
k++;
}
if(k==lenw)
{
ans++;
k=fail[k-];
}
}
}
int main()
{
int t1;
scanf("%d",&t1);
while(t1--)
{
input();
make_fail();
ans=;
kmp();
printf("%d\n",ans);
}
return ;
}

3.【AC自动机】

BZOJ 3172: [Tjoi2013]单词

Description

某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

Input

第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

Output

输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

Sample Input

3
a
aa
aaa

Sample Output

6
3
1
代码:

#include<iostream>
using namespace std;
#define N 1000100/*最长字符串的长度*/
#include<cstring>
#include<cstdio>
int topt=,n;
struct Trie{
int nxt[],cnt,fail;
Trie()
{
memset(nxt,,sizeof(nxt));
cnt=fail=;/*结构体初始化*/
}
}trie[N];
int pos[],que[N],head=-,tail=-;
void build_trie(int k,char*str)/*建trie书的过程*/
{
int now=;
while(*str)
{
if(!trie[now].nxt[*str-'a'])
trie[now].nxt[*str-'a']=++topt;
now=trie[now].nxt[*str-'a'];
str++;
trie[now].cnt++;/*记录该前缀出现的次数*/
}
pos[k]=now;/*记录第k个单词终点的节点编号*/
}
void input()
{
scanf("%d",&n);
for(int i=;i<=n;++i)
{
char s[N];
scanf("%s",s);
build_trie(i,s);
}
}
void make_fail()/*生成fail数组*/
{
int now=;
trie[now].fail=;
for(int i=;i<;++i)/*根节点及第一层点的入队处理*/
{
if(!trie[now].nxt[i]) continue;
que[++tail]=trie[now].nxt[i];
trie[trie[now].nxt[i]].fail=;
}
int p;
while(head<tail)
{
++head;
now=que[head];
for(int i=;i<;++i)
{
if(!trie[now].nxt[i]) continue;
que[++tail]=trie[now].nxt[i];/*如果存在,就入队*/
p=trie[now].fail;/*p是该节点父亲的fail指针*/
while(!trie[p].nxt[i]&&p)/*回调的过程*/
p=trie[p].fail;
if(trie[p].nxt[i])
trie[trie[now].nxt[i]].fail=trie[p].nxt[i];
else trie[trie[now].nxt[i]].fail=;
}
}
for(int i=tail;i>=;--i)
trie[trie[que[i]].fail].cnt+=trie[que[i]].cnt/*关键:从队列的反方向,因为是广搜,所以反方向的1<--3<--5都有该单词的cnt,只有反向才能把cnt一层层传上来,因为fail不一定会指向我们想要的位置*/;
for(int i=;i<=n;++i)
printf("%d\n",trie[pos[i]].cnt);/*这是该单词的这终结点,但是也许别的单词中也会包括该单词,因为这是广搜,所以包含该单词的单词终结位置的fail一定指向当前这个单词,上面那一步就是,把这里的单词数转移上去*/
}
int main()
{
input();
make_fail();
return ;
}

4.【manacher算法--回文串】

POJ 3974 Palindrome
Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 6831   Accepted: 2534

Description

Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?"

A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not.

The students recognized that this is a classical problem but couldn't come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I've a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I've an even better algorithm!".

If you think you know Andy's final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

Input

Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity). 

Output

For each test case in the input print the test case number and the length of the largest palindrome. 

Sample Input

abcbabcbabcba
abacacbaaaab
END

Sample Output

Case 1: 13
Case 2: 6

题目大意:求最长回文子串的长度

#define L 1000100
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
using namespace std;
char s[L*+];
int p[L*+],id;
int lens;
int ans=-;
void input()
{
lens=strlen(s);
for(int i=lens;i>=;--i)
{
s[i+i+]=s[i];/*预处理加#,偶数是原字母,奇数和0是#*/
s[i+i+]='#';
}
s[]='#';
}
void manacher()
{
ans=;
id=;p[id]=;
for(int i=;i<=lens*+;++i)/*别忘了跑2*lens+2才可以*/
{
if(id+p[id]>i)
p[i]=min(p[*id-i],id+p[id]-i);
while(s[i+p[i]]==s[i-p[i]])
p[i]++;
if(i+p[i]>id+p[id])
id=i;
ans=max(ans,p[i]);
}
}
int main()
{
int topt=;
while(scanf("%s",s)==)
{
++topt;
if(strcmp(s,"END")==) break;
input();
manacher();
printf("Case %d: %d\n",topt,ans-);/*ans-1是因为添加了#*/
memset(s,,sizeof(s));/*不要忘记初始化*/
memset(p,,sizeof(p));
}
return ;
}

清北学堂学习总结 day2 字符串 练习的更多相关文章

  1. 清北学堂学习总结day2

    今天是钟皓曦大佬讲课,先来膜一波   %%%%% •数论 数论是这次培训的一个重点,那么什么是数论呢? 数论是研究整数性质的东西,所以理论上day2不会涉及小数QwQ (切入正题) •整除性: 设a, ...

  2. 清北学堂学习总结day1

    上午篇 一.高精度计算: [以下内容先只考虑非负数情况] •高精度加法: 思路:[模拟竖式运算] 注意:[进位] •高精度减法: 思路:[同加法类似,模拟竖式运算,进位变退位] 注意: [结果为负数的 ...

  3. 清北学堂学习总结day3

    小学知识总结 上午篇 •积性函数的卷积公式 (1)(f * g)( n ) = ∑(d|n) f( d ) x g ( n / d ) (2)代码实现 LL f[N], g[N], h[N]; voi ...

  4. 清北学堂学习总结 day1 数据结构 练习

    1.二叉搜索树 STL set直接做就可以了 2.树状数组+差分数列: codevs 1081 线段树练习 2  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Maste ...

  5. 7月清北学堂培训 Day 3

    今天是丁明朔老师的讲授~ 数据结构 绪论 下面是天天见的: 栈,队列: 堆: 并查集: 树状数组: 线段树: 平衡树: 下面是不常见的: 主席树: 树链剖分: 树套树: 下面是清北学堂课程表里的: S ...

  6. 清北学堂2017NOIP冬令营入学测试P4745 B’s problem(b)

    清北学堂2017NOIP冬令营入学测试 P4745 B's problem(b) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描 ...

  7. 清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)

    清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算 ...

  8. 济南清北学堂游记 Day 1.

    快住手!这根本不是暴力! 刷了一整天的题就是了..上午三道题的画风还算挺正常,估计是第一天,给点水题做做算了.. rqy大佬AK了上午的比赛! 当时我t2暴力写挂,还以为需要用啥奇怪的算法,后来发现, ...

  9. 清明培训 清北学堂 DAY1

    今天是李昊老师的讲授~~ 总结了一下今天的内容: 1.高精度算法 (1)   高精度加法 思路:模拟竖式运算 注意:进位 优化:压位 程序代码: #include<iostream>#in ...

随机推荐

  1. qq上传文件进行测试要点分析

    功能 QQ 兼容性 1.Win系统/Mac系统  Android/IOS 品牌 传 1.上传方式:直接拖拽,按回车键上传 2.多个文件同时上传给一人/多人(考虑稳定性,是否存在内存泄露) 3.不是好友 ...

  2. 【IDEA】与Eclipse "Link with Editor"等价功能设置

    Link With Editor是Eclipse内置功能中十分小巧,但却异常实用的一个功能.这个开关按钮 (Toggle Button) 出现在各式导航器视图 ( 例如 Resource Explor ...

  3. linux下C语言实现的哈希链表【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4276934.html 操作系统:ubuntu10.04 前言:     在稍微大点的项目中,基本都会遇到算 ...

  4. Ubuntu10.04 下安装RabbitVCS

    安装RabbitVCS的方法步骤如下: 1.sudo add-apt-repository ppa:rabbitvcs/ppa       #将rabbitvcs的添加到源里面.(次操作会提示是否要添 ...

  5. FusionCharts 用法心得

    现在主流的很多jQuery+js结合的图表展示插件,有HighCharts,ECharts等等,今天我们先来了解一下FusionCharts,也是一个非常不错的图表制作工具.希望我的同事以及其他需要帮 ...

  6. 2017百度春招<不等式排列>

    题目: 度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 '>' 和 '<' )使其成为一个合法的不等式数列.但是现在度度熊 ...

  7. spring源码解析--事务篇(前篇)

    对于每一个JAVA程序员,spring应该是再熟悉不过的框架了,它的功能有多强大我就不多说了,既然他有这么强大的功能,是如何实现的呢?这个就需要从他的原理去了解,而最直接了解原理的方式莫过于源码.当然 ...

  8. Linux下突然不识别无线网卡

    昨天还能用wifi的Linux,今天进去后发现没有了wifi的图标,ifconfig也不显示无线网卡.怎么办? 出现这种情况,肯定是上次关机之前做了一些操作导致的.我遇到过的一个情况是:Fedora2 ...

  9. 【PAT】1005. 继续(3n+1)猜想 (25)

    1005. 继续(3n+1)猜想 (25) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中 ...

  10. [实战]MVC5+EF6+MySql企业网盘实战(11)——新建文件夹2

    写在前面 上篇文章实现了创建文件夹的功能,这里面将实现单击文件夹,加载列表的功能. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网 ...