文章目录
#10034. 「一本通 2.1 例 2」图书管理
代码
#include "stdio.h"
#include "string.h"
const int mod1 = 1e6 + 3, mod2 = 1e6 + 9, p1 = 47, p2 = 79, N = 30009;
int book[N], a[mod2 + 8], b[mod2 + 8];
int shu = 0;
void lianbiao(int x, int y) {
book[++shu] = a[x]; //book[++shu]=a[x]上一个标记值
a[x] = shu;
b[shu] = y; //有且只有一个(很重要)
}
int find(int x, int y) {
for (int i = a[x]; i != 0 ; i = book[i]) {
if (b[i] == y)
return 1;
}
return 0;
}
int main() {
int n, i, j;
scanf("%d", &n);
char c[10], cc[1000];
while (n--) {
scanf("%s", c);
gets(cc);
int x = 0, y = 0;
for (i = 0; i < strlen(cc); i++) {
//x,y双哈希思想,两关键字决定一个字符,减小误差
x = (x * p1 + cc[i]) % mod1;
y = (y * p2 + cc[i]) % mod2;
}
if (c[0] == 'a')
lianbiao(x, y);
else {
if (find(x, y))
printf("yes\n");
else
printf("no\n");
}
}
}
#10035. 「一本通 2.1 练习 1」Power Strings
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000005];
int nxt[1000005],l;
void getnext()
{
int k=-1,j=0;
nxt[0]=-1;
while(j<l)
{
if(k==-1||s[k]==s[j])
{
k++;j++;
nxt[j]=k;
}
else
k=nxt[k];
}
}
int main()
{
while(~scanf("%s",s))
{
if(s[0]=='.')
break;
l=strlen(s);
getnext();
if(l%(l-nxt[l]))
printf("1\n");
else
printf("%d\n",l/(l-nxt[l]));
}
return 0;
}
#10036. 「一本通 2.1 练习 2」Seek the Name, Seek the Fame
没写
#2823. 「BalticOI 2014 Day 1」三个朋友
代码
#include "stdio.h"
#include "algorithm"
#include "string.h"
#include "math.h"
using namespace std;
#define ull unsigned long long
char c[2000009];
ull a[2000009],b[2000009];
int main()
{
ull l,t=0,s,sum;
scanf("%llu%s",&l,c+1);
if(l%2==0)
{
printf("NOT POSSIBLE\n");
return 0;
}
b[0]=1;//131好像是根据字符对应的最大数字对比得到的
for(int i=1; i<=l; i++)
{
a[i]=a[i-1]*131+c[i];
b[i]=b[i-1]*131; //注意:b[1]=131,为什么b[1]不是1而是131,值得思考
}
for(int i=1; i<=l; i++)
{
ull k,j;//k记录前半段,j记录后半段
if(i<=l/2+1)//前半段加了字符,第i个就是加入的字符
k=a[l/2+1]-a[i]*b[l/2+1-i]+a[i-1]*b[l/2+1-i];
// 第二个a是插入的:aabbaa
// -> aabbaa-aa*131*131*131*1=bbaa
// -> bbaa+a*131*131*131*1=abbaa
else
k=a[l/2];
if(i<=l/2+1)//i<l/2+i都可以看个人喜好
j=a[l]-a[l/2+1]*b[l/2];
else
j=a[l]-a[i]*b[l-i]+(a[i-1]-a[l/2]*b[i-1-l/2])*b[l-i];
if(k==j)
{
if(t&&sum!=k)//注意:aaaaa如果没有sum,则会输出NOT UNIQUE
{
printf("NOT UNIQUE\n");
return 0;
}
t=1,s=i,sum=k;
}
}
if(!t)
{
printf("NOT POSSIBLE\n");
return 0;
}
if(s<=l/2+1)
printf("%s",c+l/2+2);
else
{
for(int i=1; i<=l/2; i++)
printf("%c",c[i]);
}
}
#10041. 「一本通 2.1 练习 7」门票
代码
//1ll是为了在计算时,
//把int类型的变量
//转化为long long
//单哈希做法很好想,但是冲突概率极大以至于无法通过此题,
//所以考虑使用双哈希。
//双哈希一般是不会被卡掉的,直接认为是正确的就好了
#include "stdio.h"
#include "algorithm"
#include "string.h"
const int N=1e6,p1=249439,p2=249449;//1e6+7 和 1e6+9超内存
//414971和 414977是质数
int vis1[p1];
int vis2[p2];//双哈希
int main()
{
int s1=1;
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
vis1[1]=vis2[1]=1;//a0=0;
for(int i=1; i<=N; i++)
{
s1=(1ll*a*s1+s1%b)%c;
int m1=s1%p1;
int m2=s1%p2;
// printf("%d %d %d\n",s1,m1,m2);
if(vis1[m1]&&vis1[m1]==vis2[m2])
{
printf("%d\n",i);
return 0;
}
if(!vis1[m1]) vis1[m1]=i;
if(!vis2[m2]) vis2[m2]=i;
}
printf("-1\n");
}
#10042. 「一本通 2.1 练习 8」收集雪花
代码
#include "stdio.h"
#include "algorithm"
#include "iostream"
#include "map"
using namespace std;
int a[1000006];
map<int,int>mp;
int main()
{
int n,m,l=1;
int len=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(mp.count(a[i]))//a[i]出现的次数或写成mp.find(a[i])!=mp.end()
{
while(a[l]!=a[i])
{
mp.erase(mp.find(a[l]));//删a[l]
l++;
}
l++;
}
else
mp[a[i]]=1;
len=max(len,i-l+1);
}
cout<<len<<endl;
}
#10043. 「一本通 2.2 例 1」剪花布条
代码
#include "stdio.h"
#include "string.h"
char a[1009],c[1009];
int b[1009];
int main()
{
while(~scanf("%s",a))
{
memset(b,0,sizeof(b));
int l1=strlen(a);
if(l1==1&&a[0]=='#')
break;
scanf("%s",c);
int l2=strlen(c);
int i,j;
for(i=0; i<l2; i++)
{
j=i;
while(j!=0)
{
j=b[j];
if(c[i]==c[j])
{
b[i+1]=j+1;
break;
}
}
}
j=0;
int s=0;
for(i=0; i<l1; i++)
{
while(a[i]!=c[j]&&j)//while要在if上面,while过后进行if
j=b[j];
if(a[i]==c[j])
{
j++;
if(j==l2)
{
s++;
j=0;
}
continue;
}
}
printf("%d\n",s);
}
}
#10035. 「一本通 2.1 练习 1」Power Strings
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000005];
int nxt[1000005],l;
void getnext()
{
int k=-1,j=0;
nxt[0]=-1;
while(j<l)
{
if(k==-1||s[k]==s[j])
{
k++;j++;
nxt[j]=k;
}
else
k=nxt[k];
}
}
int main()
{
while(~scanf("%s",s))
{
if(s[0]=='.')
break;
l=strlen(s);
getnext();
if(l%(l-nxt[l]))
printf("1\n");
else
printf("%d\n",l/(l-nxt[l]));
}
return 0;
}