2013程式設計之美全國挑戰賽 相似字串

2021-06-16 15:02:15 字數 2035 閱讀 4396

總time limit: 

8000ms 

memory limit: 

262144kb

description

對於兩個長度相等的字串,我們定義其距離為對應位置不同的字元數量,同時我們認為距離越近的字串越相似。例如,「0123」和「0000」的距離為 3,「0123」和「0213」的距離則為 2,所以與「0000」相比,「0213」和「0123」最相似。

現在給定兩個字串 s1 和 s2,其中 s2 的長度不大於 s1。請在 s1 中尋找乙個與 s2 長度相同的子串,使得距離最小。

input

輸入包括多組資料。第一行是整數 t,表示有多少組測試資料。每組測試資料恰好佔兩行,第一行為字串 s1,第二行為 s2。所有字串都只包括「0」到「9」的字元。

1 ≤ t ≤ 100 

小資料:字串長度不超過 1000 

大資料:字串長度不超過 50000

output

對於每組測試資料,單獨輸出一行「case #c: d」。其中,c 表示測試資料的編號(從 1 開始),d 表示找到的子串的最小距離。

sample input

3

0123456789

321010203040506070809

40420121221

211

sample output

case #1: 2

case #2: 1

case #3: 1

解題思路:
這道題要求在s1中尋找與s2對應位置相同字元最多的子串。

對於小資料,通過列舉子串起點,再按照定義計算距離就可以通過。對於大資料,我們需要更高效的演算法。

不過看了官方給出的解題報告,用fft看不懂t_t。

如下:
如果可以「批量」地計算出s1中所有長度為|s2|的子串與s2的相同字元數量,那麼剩下的問題就僅僅是在這些數量值中尋找最大值了。對於s2和s1中的任意乙個長度為|s2|的子串,顯然這兩個字串相同字元的數量是'0', '1', ..., '9'各自相同字元數的總和,所以我們首先只考慮關於單個字元c的相同字元數量。於是可以把s1和s2看作成兩個01序列:字元c對應於1,其他字元對應於0。具體地說,記s1和s2的長度分別為n1和n2,構造兩個序列:

x[n] = x[n modn1] = (s1[n mod n1] == c) ? 1 : 0

y[n] = (s2[n2 -n - 1] == c) ? 1 : 0

其中x是迴圈序列,y對s2頭尾調轉。聰明的你一定發現了,這兩個序列卷積的第n項(x * y)[n]就是s1[n + 1 ... n + n2]與s2相同的c字元的數量,而卷積可以利用fft在o(nlogn)時間內計算(

於是我們可以得到這樣乙個o(nlogn)的演算法:對於每個字元c,構造序列x和y,使用fft計算卷積,最後把結果相加,找最大值即可。需要注意的是,fft中涉及的大量sin和cos的計算結果需要提前預處理,否則很容易超時。

因為計算一次卷積需要執行3次fft,所以上面的演算法總共需要執行30次fft,常數很大。別忘了fft可以計算複數域的卷積,利用這個特點可以一次處理兩種字元c1和c2,只需稍稍修改下x和y的定義。在x中,c1對應於1,c2對應於i,其他字元對應於0;在y中恰好相反,c1對應於i,c2對應於1,其他字元對應於0。若記卷積第n項(x * y)[n]為a + bi,那麼b就是c1和c2的相同字元總數。經過這樣的修改,計算量減少一半。

//

借鑑乙個排名第二(chaozicen)的大牛的方法:不過感覺這道題最壞情況也是平方演算法,因為有巢狀的for迴圈,官方給出的能優化到nlogn.
#include #include #include #include #include using namespace std;

vectore[10];

int ans[60000];

int main()

} int dis=0;

for(int i=0;idis)dis=ans[i];

} dis=len2-dis;

cout<<"case #"<

2013程式設計之美全國挑戰賽

description alice和bob都要向同乙個商人購買鑽石。商人手中有 n 顆鑽石,他會將它們一顆顆地賣給他們,alice和bob通過競價的方式來決定鑽石的歸屬。具體的過程如下 商人首先指定其中乙個人開始 之後兩人輪流 要求是一定要比對方報的 更高。任何時候,如果乙個人不願出價或者出不起價錢...

2013程式設計之美全國挑戰賽

description 對於兩個長度相等的字串,我們定義其距離為對應位置不同的字元數量,同時我們認為距離越近的字串越相似。例如,0123 和 0000 的距離為 3,0123 和 0213 的距離則為 2,所以與 0000 相比,0213 和 0123 最相似。現在給定兩個字串 s1 和 s2,其中...

2013程式設計之美全國挑戰賽 競價

description alice和bob都要向同乙個商人購買鑽石。商人手中有 n 顆鑽石,他會將它們一顆顆地賣給他們,alice和bob通過競價的方式來決定鑽石的歸屬。具體的過程如下 商人首先指定其中乙個人開始 之後兩人輪流 要求是一定要比對方報的 更高。任何時候,如果乙個人不願出價或者出不起價錢...