• Cyclic Nacklace HDU


    CC这个月底总是很郁闷,昨天他查了他的信用卡,没有任何意外,只剩下99.9元了。他很苦恼,想着如何度过这最后的几天。受“HDU CakeMan”企业家精神的启发,他想卖一些小东西来赚钱。当然,这并非易事。圣诞节就要到了,男孩们都忙着挑选圣诞礼物送给女朋友。人们认为,链手镯是一个很好的选择。然而,事情并不总是那么简单,众所周知,女孩喜欢用五颜六色的装饰来使手镯显得生动活泼,同时她们也想展示自己作为大学生成熟的一面。CC了解了女孩们的需求后,打算出售这款名为CharmBracelet的chain bracelet。这个CharmBracelet是由五颜六色的珍珠组成的,为了展现女孩的活泼,最重要的是它必须有一个环链连接,这意味着珍珠的颜色是从左到右的环链连接的。循环计数必须大于1。如果你把这条链子最左边的珍珠和最右边的珍珠连接起来,你就可以做成一个迷人的手镯。如下图所示,这个CharmBracelet的cycle是9,cycle count是2:现在CC带来了一些普通的手链,他想买最少数量的珍珠来做charmbracelet,这样他可以节省更多的钱。但是在重新制作手链的时候,他只能在链的左端和右端添加彩色珍珠,也就是说,中间添加是禁止的。CC对他的想法很满意,请您帮助。

    输入输入的第一行是单个整数T (0 < T <= 100),表示测试用例的数量。每个测试用例只包含一行描述要重做的原始普通链。字符串中的每个字符代表一颗珍珠,共有26种珍珠由“a”~“z”字符描述。字符串长度Len:(3 <= Len <= 100000)。

    输出每一个箱子,你被要求输出的最低数量的珍珠添加到一个CharmBracelet。

    样例输入

    3
    aaa
    abca
    abcde

    Sample Output

    0
    2
    5

    题意:

    就是给你一个字符串,让你是这个字符串变成一个至少有两个循环节的字符串,问至少添加几个字符可以达到这样的目的

    添加字符只能在头部和尾部添加不能在中间添加(这是个环)

    题解:

    KMP最小循环节、循环周期:
    定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。
    (1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。
    (2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。
    证明看这里--------->    点击
     
    知道定理了那么这道题也就不难了
     
    代码:
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=100005;
     7 const int INF=0x3f3f3f3f;
     8 char ptr[maxn];
     9 void get_next(int len,int *next)
    10 {
    11     next[0]=-1;
    12     int k=-1;
    13     for(int i=1;i<=len-1;++i)
    14     {
    15         while(k>-1 && ptr[k+1]!=ptr[i])
    16             k=next[k];
    17         if(ptr[k+1]==ptr[i])
    18         {
    19             k+=1;
    20         }
    21         next[i]=k;
    22     }
    23 }
    24 int main()
    25 {
    26     int t;
    27     scanf("%d",&t);
    28     while(t--)
    29     {
    30         scanf("%s",ptr);
    31         int len=strlen(ptr);
    32         int next[len];
    33         get_next(len,next);
    34         int length=len-(next[len-1]+1);
    35         if(len != length && len%length == 0)
    36         {
    37             printf("0
    ");
    38         }
    39         else
    40         {
    41             int add=length-(next[len-1]+1)%length;
    42             printf("%d
    ",add);
    43         }
    44     }
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    shell脚本获取当前时间
    shell脚本读取用户输入并与之交互
    shell脚本获取客户端IP
    shell脚本中重启tomcat进程
    性能测试经验
    cmdhere的两种方法
    tomcat启动多个应用时报内存溢出
    [kuangbin]带你飞之'连通图'专题
    (模板)解决带负权最短路径 Bellman-ford 与 SPFA(前者的队列优化)
    [kuangbin]带你飞之'最短路练习'专题
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11194892.html
Copyright © 2020-2023  润新知