1. 程式人生 > 實用技巧 >UVa455 - Periodic Strings 題解

UVa455 - Periodic Strings 題解

題目

題目連結

UVa455 - Periodic Strings

題目大意

一個有用週期k的字串是指他可以被一個長度為k的子串重複一定次數得到。比如字串"abcabcabcabc"的週期是3,它是由子串"abc"重複4次得到的。它的週期也可以是6("abcabc"重複2次),也可以是12("abcabcabcabc"重複1次)。現在寫一個程式來找出它的最小週期。

輸入第一行為測試資料數量T。之後的輸入為測試資料。測試資料為長度小於等於80的不含空格的字串。每行測試資料之間有一個空行(包括與T之間)。

輸出為每個測試資料的最小週期。兩個輸出之間有一個空行。

樣例輸入

1

HoHoHo

樣例輸出

2

題解

這道題很容易解決,從週期為1開始嘗試,能夠通過重複把整個字串給製作出來的週期,就是好週期(滑稽.jpg)。

然而這道題最噁心的就是輸入輸出了。注意輸入之間有空行,從原題目那裡複製輸入樣例是沒有空行的。而輸出卡了我好久,吐血。

Then show the code.

#include <stdio.h>
#include <string.h>

int main(){
    int T;
    scanf("%d", &T);
    char s[100], temp[100];
    while(T--){
        //獲取輸入之間的空行
        getchar();

        int len, minPeri, flag;
        memset(s, 0, sizeof(s));
        scanf("%s", s);
        len = minPeri = strlen(s);

        for(int i=1; i<=len; i++){
            //如果字串不能整除假設的週期i,那麼i肯定不是週期
            if(len%i) continue;

            //flag=1為先假設i為最小週期
            //temp陣列為假設的最小週期對應的子串
            flag = 1;
            memset(temp, 0, sizeof(temp));
            for(int j=0; j<i; j++)
                temp[j] = s[j];
            
            
            for(int j=0; j<len/i; j++){
                for(int k=0; k<i; k++){
                    //發現字串與子串對應的元素不相同就及時退出
                    if(temp[k] != s[i*j+k]){
                        flag = 0;
                        break;
                    }
                }
                //flag為0就確定i肯定不是週期 直接break
                if(!flag) break;
            }

            if(flag){
                minPeri = i; 
                break;
            }      
        }
        //注意這裡的輸出
        //每個輸出資料行之間要有一個空行
        //在最後一個輸出資料之後不能2個空行
        printf("%d\n", minPeri);
        if(T) printf("\n");
    }
    return 0;
}