月考(cogs 1176)

【题目描述】

在上次的月考中Bugall同学违反了考场纪律还吃了处分,更可气的是在第二天的校会时
 间学校就此事做了全校通报. 现已知在当天校会时间有总共N个同学听到了有关Bugall的处分决定.
 
 Bugall同学在铁一有M个朋友,这M个人中有的可能听到了当天的处分决定,有的可能没
 有听到,现在Bugall同学想知道他有几个朋友听到了当天的处分通报.

【输入格式】

第一行为一个整数N,从第2行到N+1行,每行用一个长度不超过200的字符串表示
 一个人的名字.
  第N+2行为一个整数M,从第N+3行到N+M+2行,每行用一个长度不超过200的字符
 串表示Bugall同学一个朋友的名字.

【输出格式】

输出有几个Bugall同学的铁一朋友在当天的校会时间听到了Bugall处分通报.保证不重名。

【样例输入】

3
Dazui
Erge
Dapigu
2
Varpro
Erge

【样例输出】

1
/*跑的略慢的版本,用链表写的*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define lon long long
#define mod 13212377
#define N 80010
using namespace std;
int head[mod+10];int n,cnt;
char s1[210];string s2;
struct node{
    int pre;string ss;
};node e[N];
lon poww(lon a,lon b){
    lon base=a,r=1;
    while(b){
        if(b&1)r*=base;
        base*=base;
        r%=mod;
        base%=mod;
        b>>=1;
    }
    return r;
}
void add(){
    lon tot=(s2[0]-'A'+1);int len=s2.length();
    for(int i=1;i<len;i++){
        tot+=(s2[i]-'a')*poww(26,i);
        tot%=mod;
    }
    e[++cnt].ss=s2;
    e[cnt].pre=head[tot];
    head[tot]=cnt;
}
bool find(){
    lon tot=(s2[0]-'A'+1);int len=s2.length();
    for(int i=1;i<len;i++){
        tot+=(s2[i]-'a')*poww(26,i);
        tot%=mod;
    }
    for(int i=head[tot];i;i=e[i].pre)
        if(e[i].ss==s2)return true;
    return false;
}
int main(){
    freopen("mtest.in","r",stdin);
    freopen("mtest.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s1);
        int len=strlen(s1);s2="";
        for(int j=0;j<len;j++)
            s2+=s1[j];
        add();
    }
    scanf("%d",&n);int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%s",s1);
        int len=strlen(s1);s2="";
        for(int j=0;j<len;j++)
            s2+=s1[j];
        if(find())ans++;
    }
    printf("%d",ans);
    return 0;
}
/*
  今天听YLF大神说了一种从来没听说过的hash的实现方式:自然溢出。
   就是让系统自动对用一个大数对我们的数据取模,虽然可能会发生hash碰撞,但概率很小,而且很快。 
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define P 26
#define p 17
#define N 80010
#define mod 13457
using namespace std;
char s[210];int head[mod+10],n,cnt;
struct node{
    int v,pre,sum;
};node e[N];
int Has(){
    int len=strlen(s),tot=s[0]-'A'+1;
    for(int i=0;i<len;i++)
        tot=tot*P+s[i]-'a'+1;
    return tot;
}
int has(){
    int len=strlen(s),tot=s[0]-'A'+1;
    for(int i=0;i<len;i++)
        tot=(tot*p+s[i]-'a'+1)%mod;
    return tot;
}
void add(){
    int Ha=Has();
    int ha=has();
    if(ha<0)ha=-ha;
    for(int i=head[ha];i;i=e[i].pre){
        if(e[i].v==Ha){
            e[i].sum++;return;
        }
    }
    ++cnt;
    e[cnt].v=Ha;
    e[cnt].sum++;
    e[cnt].pre=head[ha];
    head[ha]=cnt;
}
int query(){
    int Ha=Has();
    int ha=has();
    if(ha<0)ha=-ha;
    for(int i=head[ha];i;i=e[i].pre){
        if(e[i].v==Ha)return e[i].sum;
    }
    return 0;
}
int main(){
    freopen("mtest.in","r",stdin);
    freopen("mtest.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        add();
    }
    scanf("%d",&n);int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        ans+=query();
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2016-11-16 15:28  karles~  阅读(330)  评论(0编辑  收藏  举报