zoukankan      html  css  js  c++  java
  • [HDOJ3746]Cyclic Nacklace

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746

    Cyclic Nacklace

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4372    Accepted Submission(s): 1986


    Problem Description
    CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of "HDU CakeMan", he wants to sell some little things to make money. Of course, this is not an easy task.

    As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to everyone, girl's fond of the colorful decoration to make bracelet appears vivid and lively, meanwhile they want to display their mature side as college students. after CC understands the girls demands, he intends to sell the chain bracelet called CharmBracelet. The CharmBracelet is made up with colorful pearls to show girls' lively, and the most important thing is that it must be connected by a cyclic chain which means the color of pearls are cyclic connected from the left to right. And the cyclic count must be more than one. If you connect the leftmost pearl and the rightmost pearl of such chain, you can make a CharmBracelet. Just like the pictrue below, this CharmBracelet's cycle is 9 and its cyclic count is 2:
    【此处应有图】

    Now CC has brought in some ordinary bracelet chains, he wants to buy minimum number of pearls to make CharmBracelets so that he can save more money. but when remaking the bracelet, he can only add color pearls to the left end and right end of the chain, that is to say, adding to the middle is forbidden.
    CC is satisfied with his ideas and ask you for help.
     
    Input
    The first line of the input is a single integer T ( 0 < T <= 100 ) which means the number of test cases.
    Each test case contains only one line describe the original ordinary chain to be remade. Each character in the string stands for one pearl and there are 26 kinds of pearls being described by 'a' ~'z' characters. The length of the string Len: ( 3 <= Len <= 100000 ).
     
    Output
    For each case, you are required to output the minimum count of pearls added to make a CharmBracelet.
     
    Sample Input
    3 aaa abca abcde
     
    Sample Output
    0 2 5
     
     
    给你一个字符串,让你求出使此串至少循环两次要添加的字符数量。
    如:
     
    aaa不需要添加任何字符,所以输出0
    abca,循环节认为是abc,那么至少要循环2次,则需要额外添加2个字符。
    abcde,无循环节,因此重复本串,就是5个字符。
     
     
    下面说下思路:
      如同POJ2752的那个题一样,还是考察对于pre(next)数组的理解,(POJ2752题题解:http://www.cnblogs.com/vincentX/p/4758339.html)
      我们取最后一个pre值pre[n]=k,它代表的含义为整个字符串前k个字符和后k个字符相等。那么我们可以用整串的长度减去pre[n],也就是减掉最后的那pre[k]个字符,那么得到的是该串循环节的长度。
      这么想就很好理解了,我们接下来看一下样例:
     
    "aaa" pre[n] = 2,即前2个字符和后2个字符相等(注:pre[n] = n = 3的时候是没有意义的),我们用总长减去pre[n],即 3 - 2 = 1,剩下的串(循环节)为"a"
    "abca" pre[n] = 1,即第一个字符和最后一个字符相等,4 - 1 =3,剩下的串为 "abc"
    "abcde" pre[n] = 0,循环节是5,整串看作循环节 "abcde"
     
     
      先考虑如何求添加的字符的个数:
     
        我们添加字符是以最后pre[n]个字符为标准的,因为他们不在循环节内,添加的字符数一定小于等于循环节(loop)的长度(如果pre[n]=0的话,那么就把整个串再添加一遍),那么一般情况下,去掉现有的pre[n],再需要额外添加的字符就是:
     
        loop - (pre[n] % loop)
     
        特别地,如果串本身不需要添加任何字符,即:循环至少两次。除了保证串长可以被循环节整除以外,还应保证串长不应该等于循环节长度。
     
        n != loop && n % loop == 0
     
    代码如下:
     
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <iostream>
     6 #include <cmath>
     7 #include <queue>
     8 #include <map>
     9 #include <stack>
    10 #include <list>
    11 #include <vector>
    12 
    13 using namespace std;
    14 
    15 const int maxn = 100010;
    16 int na, nb;
    17 char a[maxn];
    18 char b[maxn];
    19 int pre[maxn];
    20 
    21 //b是模式串,a是目标串
    22 void getpre(char *b, int *pre) {
    23     int j, k;
    24     pre[0] = -1;
    25     j = 0;
    26     k = -1;
    27     while(j < nb) {
    28         if(k == -1 || b[j] == b[k]) {
    29             j++;
    30             k++;
    31             pre[j] = k;
    32         }
    33         else {
    34             k = pre[k];
    35         }
    36     }
    37 }
    38 
    39 int kmp() {
    40     int ans = 0;
    41     int i = 0;
    42     int j = 0;
    43     getpre(b, pre);
    44     while(i < na) {
    45         if(j == -1 || a[i] == b[j]) {
    46             i++;
    47             j++;
    48         }
    49         else {
    50             j = pre[j];
    51         }
    52         if(j == nb) {
    53             ans++;
    54         }
    55         if(i == na) {
    56             return ans;
    57         }
    58     }
    59 }
    60 
    61 int main() {
    62     freopen("in", "r", stdin);
    63     int T;
    64     scanf("%d", &T);
    65     while(T--) {
    66         scanf("%s", b);
    67         nb = strlen(b);
    68         getpre(b,pre);
    69         int loop = nb - pre[nb];
    70         if(nb != loop && nb % loop == 0) {
    71             printf("0
    ");
    72         }
    73         else {
    74             printf("%d
    ", loop - (pre[nb] % loop));
    75         }
    76     }
    77 }
  • 相关阅读:
    从万元户到千万富翁:6招助你蜕变
    16款有助于提升工作效率的工具
    8个身家百万的儿童创业者
    关于航模无刷电机发热问题的假想解决方案
    折腾了2个晚上无刷电调(ESC),电机终于转起来了,特此记录一下
    PWM占空比和分辨率(转)
    MSB与LSB(转)
    树莓派3uart wifi模块调试 (浪费了我3天时间的宝贵经验)
    USB加minicom使用串口
    【转】使用BBB的device tree和cape(重新整理版)
  • 原文地址:https://www.cnblogs.com/kirai/p/4759527.html
Copyright © 2011-2022 走看看