zoukankan      html  css  js  c++  java
  • hdu2609 How many 字典树+最小表示法

    Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me
    How many kinds of necklaces total have.(if two necklaces can equal by rotating ,we say the two necklaces are some).
    For example 0110 express a necklace, you can rotate it. 0110 -> 1100 -> 1001 -> 0011->0110.

    题意:给出若干字符串,问在循环同构算作同一种字符串的条件下,有多少不同字符串

    对所有串进行最小表示法的处理,去除同构情况,再将最小表示后的串插入字典树,并统计种类数。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 const int maxn=1e5+5;
     7 const int maxm=8e5+5;
     8 char s[maxn<<1];
     9 
    10 inline int max(int a,int b){return a>b?a:b;}
    11 inline int min(int a,int b){return a<b?a:b;}
    12 
    13 int nxt[maxm][2];    //字母结点
    14 int tail[maxm];        //记录某个结点是否为单词结尾,可以用bool型仅记录是否结尾,也可以int型记录其作为结尾的单词编号或记录单词出现过多少次
    15 int size,cnt;
    16 
    17 void init(){        //初始化函数
    18     nxt[0][0]=nxt[0][1]=0;
    19     memset(tail,0,sizeof(tail));
    20     size=1;
    21     cnt=0;
    22 }
    23 
    24 void insert(char s[]){    //添加单词函数
    25     int p=0;
    26     for(int i=0;s[i];i++){
    27         int &x=nxt[p][s[i]-'0'];
    28         if(!x){
    29             nxt[size][0]=nxt[size][1]=0;
    30             x=size++;
    31         }
    32         p=x;
    33     }
    34     if(!tail[p]){
    35         cnt++;
    36         tail[p]=1;
    37     }
    38 }
    39 
    40 int MINR(char s[],int l){
    41     for(int i=0;i<l;++i)s[l+i]=s[i];
    42     s[2*l]=0;
    43     int i=0,j=1;
    44     while(i<l&&j<l){
    45         int k=0;
    46         while(s[i+k]==s[j+k]&&k<l)++k;
    47         if(k==l)return min(i,j);
    48         if(s[i+k]>s[j+k])i=max(i+k+1,j+1);
    49         else j=max(j+k+1,i+1);
    50     }
    51     return min(i,j);
    52 }
    53 
    54 int main(){
    55     int n;
    56     while(scanf("%d",&n)!=EOF){
    57         init();
    58         for(int i=1;i<=n;++i){
    59             scanf("%s",s);
    60             int l=strlen(s);
    61             int pos=MINR(s,l);
    62             s[pos+l]=0;
    63             insert(s+pos);
    64         }
    65         printf("%d
    ",cnt);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    mysql中字符集和排序规则说明
    结束进程的批处理文件
    内有干货!2个人3个月怎样从零完毕一款社区App《林卡》
    九度OJ 1006 ZOJ问题 (这题測试数据有问题)
    简易版的堆的写法
    hbase
    JNDI配置c3p0连接池
    [effictive c++] 条款04 确定对象被使用前已被初始化
    第九十五题(推断一字符串是不是对称的)
    OpenFace库(Tadas Baltrusaitis)中基于Haar Cascade Classifiers进行人脸检測的測试代码
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6592467.html
Copyright © 2011-2022 走看看