码迷,mamicode.com
首页 > 其他好文 > 详细

CCC比赛T3

时间:2020-03-07 00:11:35      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:i++   char   pow   book   题目   for   次数   代码   sign   

参加了CCC

我好菜啊

 

做对的就几道水题

T3的题目大意是给一个字串,然后再给一个母串,看字串有几种排列方式在母串中出现过

(只包含小写字母)

举个例子

ab的排列在aba中出现过2种

ab和ba

数据范围是10^5(好像

 

首先是判断排列,按照全排列来判断肯定不行,所以选择使用一个数组,记录每个字母出现的次数

在母串判断的时候滑动一下就可以判断是否是字串的一种排列方式,因为只要每个字母的数量都一样,就说明是一种排列

然后如何避免排列重复呢,直接用一个hash就可以,因为这道题的数据还挺强的,我开了三个hash才过掉(也可能是因为我脸黑

反正这道题是水题,我就不多说了(找机会把后面两道题弄懂

上代码吧:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#define mod1 12582917
#define mod2 6291469
#define mod3 25165843
#define base 131
#define ULL unsigned long long
using namespace std;
inline long long rd(){
    long long x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch==-) f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-0;
    return x*f;
}
inline void write(long long x){
    if(x<0) putchar(-),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+0);
    return ;
}
char ch1[1000006],ch2[1000006];
int cnt[1006];
int num[1006];
ULL ha[1000006];
ULL poww[1000006];
int n,m;
bool book1[13000006];
bool book2[13000006];
bool book3[30000006];
int ans=0;
inline ULL geth(int l,int r){
    return ha[r]-(ha[l-1]*poww[r-l+1]);
}
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    poww[0]=1;
    for(int i=1;i<=1000006;i++) poww[i]=(poww[i-1]*base);
    cin>>ch1+1;
    cin>>ch2+1;
    n=strlen(ch1+1);
    m=strlen(ch2+1);
    for(int i=1;i<=m;i++){
        ha[i]=((ha[i-1]*base)+(ULL)(ch2[i]-a+1));
    }
    for(int i=1;i<=n;i++){
        cnt[ch1[i]-a+1]++;
    }
    for(int i=1;i<=n;i++){
        num[ch2[i]-a+1]++;
    }
    for(int i=n;i<=m;i++){
        int f=0;
        for(int j=1;j<=26;j++){
            if(cnt[j]!=num[j]){
                f=1;
                break;
            }
        }
        num[ch2[i-n+1]-a+1]--;
        num[ch2[i+1]-a+1]++;
        if(f) continue;
        ULL v1=geth(i-n+1,i);
        ULL v2=v1,v3=v1;
        v1%=mod1;
        v2%=mod2;
        v3%=mod3;
        if(!book1[v1]||!book2[v2]||!book3[v3]){
            book1[v1]=book2[v2]=book3[v3]=1;
            ans++;
        }
    }
    write(ans);
    return 0;
}

 

CCC比赛T3

标签:i++   char   pow   book   题目   for   次数   代码   sign   

原文地址:https://www.cnblogs.com/WWHHTT/p/12431637.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!