時間限制:
1000ms
記憶體限制:
65536kb
描述 輸入
輸入資料報括多組,每組為乙個全部由小寫字母組成的不含空格的使用者請求(字串),佔一行。使用者請求的長度不大於100,000。
最後一行輸入為#,作為結束的標誌。
輸出對於每組輸入,先輸出這個組的編號(第n組就是輸出「case n:」);然後輸出這組使用者請求中迴圈節最多的子串。如果乙個使用者請求中有兩個迴圈節數相同的子串,請選擇那個字典序最小的。
樣例輸入
ilovejohnsonjohnsonverymuchduckduckgo
aaabbbcccisagoodcompany
#
樣例輸出
case 1: johnsonjohnsoncase 2: duckduck
case 3: aaa
大致思路:
先窮舉長度l,然後求長度為l 的子串最多能連續出現幾次。首先連續出現1 次是肯定可以的,所以這裡只考慮至少2 次的情況。假設在原字串中連續出現2 次,記這個子字串為s,那麼s 肯定包括了字元r[0]、 r[l]、 r[l*2]、r[l*3] ……中的某相鄰的兩個。所以只須看字元r[l*i]和r[l*(i+1)]往前和往後各能匹配到多遠,記這個總長度為k,那麼這裡連續出現了k/l+1 次。最後看最大值是多少。
實現**:
#include#includeusing namespace std;
#include#includeint wa[200000],wb[200000],wv[200000],wsum[200000];
int height[200000],sa[200000],rank[200000];
int n,ans,len,pos;
char str[200000];
int r[200000];
int f[200000][20];
int a[200000],num;
int cmp(int *r,int a,int b,int l)
void da(int *r,int *sa,int n,int m) //倍增演算法 r為待匹配陣列 n為總長度 m為字元範圍 }
int get_rmq(int x , int y) //詢問x、y字尾的最長公共字首 }}
printf("case %d: ",++ca);
if(ans<2)
for(i=0;iprintf("%c",str[i+pos]);
puts("");
}return 0;
}
百度之星資格賽
1001 給你1 n這n個數字,公升序排列,接下來按照陣列a進行位置變換,a i 代表第i個數字會變到a i 位置上,a中的數字也是從1 n。現在問有多少個不同的陣列能滿足做一次變換和做三次變換結果相同。我們可以這樣分析,x y是唯一的到y的途徑,假設x y為第一次變換,因此在第三次變換的時候任然為...
2012百度之星資格賽 H 使用者請求中的品牌
時間限制 1000ms 記憶體限制 65536kb 描述 輸入輸入資料報括多組,每組為乙個全部由小寫字母組成的不含空格的使用者請求 字串 佔一行。使用者請求的長度不大於100,000。最後一行輸入為 作為結束的標誌。輸出對於每組輸入,先輸出這個組的編號 第n組就是輸出 case n 然後輸出這組使用...
2016 百度之星 資格賽
變懶了,最近做的很多題目都不想貼了。本來就sb,還那麼懶,沒救了。a沒想太多,設個逆元就過了。b斐波那契數列高精度。n 0時輸出換行。c字典樹,記錄結點的單詞數 以及 當前結點是否是單詞的末尾,delete時需要先找出字首對應的串數,那麼就dfs統計末尾結點總數,然後用字首減掉就好了。一開始dfs跑...