編程之美初賽第二場 題目2 : 字符串壓縮

時間限制:8000ms
單點時限:4000ms
內存限制:256MB

描述

你的硬盤上有一個神祕的文件佔用了大量空間,你決定將其壓縮以節省空間。不幸的是,你尚未安裝任何壓縮軟件,因此你決定本身編寫一個壓縮程序。你發現這是一個文本文件,包括不少行。每行是一個長度剛好爲L的字符串,並且字符串可能有重複。行的順序並不重要,換言之,打亂順序以後仍然能夠認爲文件內容和原來相同。ios

例如,這個文件的內容能夠是這樣的:json

barapi

car數組

bat框架

catpost

cat測試

 

通過一段時間觀察,你發現同一列的字符每每是相同的,因而你設計了一個簡單的壓縮框架。首先以某種策略調整行的順序,而後把全部字符串按照先列後行的順序變換成單個字符串,例如上面的例子,不調整順序則直接變換成:大數據

bcbccaaaaarrttt編碼

而後使用遊程編碼(RLE)的到壓縮變換後的字符串:spa

1b1c1b2c5a2r3t

固然也能夠先調換順序:

car

cat

cat

bat

bar

這樣的壓縮字符串爲:

3c2b5a1r3t1r

比不調整順序的稍短一些。

如今,你已經獲得了兩個不一樣的壓縮字符串,你想知道他們解壓後的文件是否相同,請寫一個程序解決這個問題。

輸入

第一行是一個整數T (T <= 30),表示測試數據組數。

每組測試數據佔三行。第一行爲整數L,表示原始文件中每一行字符串的長度。第二行和第三行分別是兩個壓縮字符串,格式如c1 n1 c2 n2 … cMnM,表示字符ci連續出現了ni次。具體格式見樣例。輸入字符串只含a到z的小寫字母,確保壓縮字符串合法有效,且不爲空。

輸出

對每組測試數據,首先輸出」Case x: 」,其中x表示測試數據編號。若是兩個壓縮字符串對應於相同的文件內容,則輸出」Yes」,不然輸出」No」。

數據範圍

小數據:1<=L<=10, 1<=ni<=100,壓縮字符串長度不超過10^4

大數據:1<=L<=1000, 1<=ni<=10^9,壓縮字符串長度不超過10^6

樣例輸入
2
3
1b1c1b2c5a2r3t
3c2b5a1r3t1r
2
20a20b10a20b10a
20a20b20a20b
樣例輸出
Case 1: Yes
Case 2: No

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 const int MAX = 10000 + 4;
 8 
 9 char str[2][MAX*3];
10 char input[MAX];
11 int L;
12 int lineNum;
13 int Num[2];
14 int visit[MAX*3];
15 
16 int main()
17 {
18     int T;
19     int n;
20     char ch1, ch2;
21     scanf("%d", &T);
22     for(int t=1; t<=T; t++) {
23         scanf("%d", &L);
24         getchar();
25         Num[0] = Num[1] = 0;
26         for(int i=0; i<2; ++i) {
27             scanf("%s", input);
28             int cur = 0;
29             int length = strlen(input);
30             for(int j=0; j<length;  ) {
31                 n = 0;
32                 while(input[j] <= '9' && input[j] >= '0') {
33                     n = n*10 + (input[j++] - '0');
34                 }
35                 Num[i] += n;
36                 for(int k=1; k<=n; k++) {
37                     str[i][cur++] = input[j];
38                 }
39                 j++;
40             }
41            // printf("%s\n", str[i]);
42         }
43         if(Num[0] != Num[1]) {
44             printf("Case %d: No\n", t);
45             continue;
46         }
47         lineNum = Num[0] / L;
48         memset(visit, -1, sizeof(visit));
49         bool res = true;
50         for(int i=0; i<lineNum; ++i) {
51             bool flag = false;
52             for(int j=0; j<lineNum; ++j) {
53                 if(visit[j] != -1) {
54                     continue;
55                 }
56                 int k;
57                 for(k=0; k<L; ++k) {
58                     if(str[0][i+k*lineNum] != str[1][j+k*lineNum]) {
59                         break;
60                     }
61                 }
62                 if(k >= L) {
63                     visit[j] = 1;
64                     flag = true;
65                     break;
66                 }
67             }
68             if(!flag) {
69                 res = false;
70                 break;
71             }
72         }
73         if(res) {
74             printf("Case %d: Yes\n", t);
75         }else {
76             printf("Case %d: No\n", t);
77         }
78     }
79     return 0;
80 }

主要是分配數組的大小,壓縮字符串不超過10^4, 1<=ni<=100, 那麼存儲的字符串至少要:

100*(10000 /(3+1)) = 25000

相關文章
相關標籤/搜索