UVa 909 - The BitPack Data Compression Problem

contents

  1. 1. Problem
  2. 2. Sample Input 1
  3. 3. Sample Output 1
  4. 4. Sample Input 2
  5. 5. Sample Output 2
  6. 6. Sample Input 3
  7. 7. Sample Output 3
  8. 8. Solution

Problem

解壓縮方式

1
2
3
4
5
6
7
8
While (there is input)
n <-- read next byte
If (0<= n <= 127)
copy the next n+1 bytes to the output as they are
Else If (129<= n <=255)
copy the next byte n-128+1 times to the output
Else If n=128
do nothing

找到用最少 bytes 的壓縮結果。每組測資只會有一筆,並且以 EOF 結尾。

範例輸出用 [ddd] 表示不可視的字符或者是可視字符都有可能,但是實際輸出直接輸出該數值的 bytes 而非以 [] 表示的字串。

Sample Input 1

1
aaaaaaaarstqahbbbbbbb

Sample Output 1

1
[135]a[5]rstqah[134]b

Sample Input 2

1
aaaaaaaaaa

Sample Output 2

1
[137]a

Sample Input 3

1
abcdefghij

Sample Output 3

1
[9]abcdefghij

Solution

討論區一而三在而三的更正解答,最後要說明的是,你們最後的答案還是錯的!此外,測試資料輸入輸出都有不可視字符是哪招,明明說一行一筆測資,以為都是可視 …
-最後討論時間為 13 年前

dp[i] 表示從 [0, i] 壓縮的最少 bytes 數量,最後使用回溯找其中一解 (任何一解都可以)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
int dp[65536], ardp[65536], from[65536], n, bb;
char s[65536];
void travel(int i) {
if(i == 0) return;
if(ardp[i] >= 129) {
travel(from[i]);
printf("%c%c", ardp[i], s[i]), bb += 2;
} else {
travel(from[i]);
printf("%c", ardp[i]), bb++;
for(int j = ardp[i]; j >= 0; j--)
printf("%c", s[i - j]), bb++;
}
}
int main() {
int idx = 1;
char c;
while((c = getchar()) != EOF)
s[idx++] = c;
{
n = strlen(s+1);
assert(n < 65536);
memset(dp, 63, sizeof(dp));
dp[0] = 0;
for(int i = 0; i <= n; i++) {
int cnt = 0;
for(int j = i+1; j <= n; j++) {
if(s[j] == s[i+1]) {
cnt++;
if(cnt + 127 > 255)
break;
if(cnt >= 2) {
if(dp[j] > dp[i] + 2)
ardp[j] = cnt + 127, from[j] = i;
dp[j] = min(dp[j], dp[i] + 2);
}
} else
break;
}
cnt = 0;
for(int j = i+1; j <= n; j++) {
cnt++;
if(cnt - 1 > 127) break;
if(dp[j] > dp[i] + cnt + 1)
ardp[j] = cnt - 1, from[j] = i;
dp[j] = min(dp[j], dp[i] + cnt + 1);
}
}
bb = 0;
travel(n);
// printf("bytes %d\n", bb);
}
return 0;
}