ACM-ICPC 2018 瀋陽賽區網絡預賽 I. Lattice's basics in digital electronics [ 01字典樹 ]

題目鏈接:

ACM-ICPC 2018 瀋陽賽區網絡預賽 I. Lattice's basics in digital electronics

題意概括:

題目給出一種處理字符串的編碼規則:

  • 以十六進制格式讀入一個字符串,轉換爲二進制
  • 把轉換後得到的二進制字符串每 9 位劃分爲一個單元,模 9 後剩餘的直接捨去
  • 對於每個 9 位長的單元,對前 8 位進行奇偶校驗:若第 9 位是 1,則若前 8 位的 1 個數是偶數時爲真;第九位是 0,則若前 8 位的 1 個數是奇數時爲真
  • 校驗爲真則保留前 8 位,假就直接刪去。校驗後第 9 位一定刪去
  • 通過以上操作,得到了一個新的二進制字符串。題目會給一種特殊的編碼方式,根據01編碼得到一個 ASCII 碼,輸出便可
  • 這種編碼方式保證不會有包含性,也就是說某一個串不會是另一個串的前綴或後綴

數據範圍:

T< 35

0< M\leq 100000 , 1\leq N\leq 256

0\leq \left | S_{i} \right |\leq 10 , 0< \left | data \right |< 200000

題解分析:

根據十六進制串經過奇偶校驗得到01串的過程就是單純模擬,仔細一點就好

用得到的 01串 來匹配編碼是這道題需要注意的地方,直接暴力肯定不現實

採用 01字典樹 來存儲所有的 01編碼 ,在編碼結束的節點存儲編碼對應的 ASCII 值,其餘節點存 0

直接從 01串 頭部開始在字典樹上進行搜索,當搜索到某一節點值不爲 0 時,便說明匹配到一個碼

由於某一個串不會是另一個串的前綴或後綴,不需要考慮 fail指針。當匹配到一個碼後,直接跳轉回到根節點繼續尋找下一個

AC代碼:

#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;

char trans[30][5] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111","1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111", "1010", "1011", "1100", "1101", "1110", "1111"};

char HTB[110][5], s[200010], bin[200010 * 4], data[200010 * 4];
int cnt = 0, M, N;

typedef struct Node {
    Node *next[2];
    int asc;
}trie;

trie *root;

void init(trie *p) {
    p->asc = 0;
    memset(p->next, NULL, sizeof(p->next));
}

void insert(char *number, int asc) {
    trie *p = root;
    for(int i = 0; number[i] != 0; i++) {
        int v = number[i] - 48;
        if(p->next[v] == NULL) {
            trie* temp = (trie*)malloc(sizeof(trie));
            init(temp);
            p->next[v] = temp;
        }
        p = p->next[v];
    }
    p->asc = asc;
}

void Clear(trie *p) {
    if (p == NULL) return;
    for (int i = 0; i < 2; i++) {
        if (p->next[i] != NULL) Clear(p->next[i]);
    }
    delete p;
}

void search(char s[]) {
    trie *p = root;
    for(int i = 0; s[i]; i++) {
        int v = s[i] - 48;
            p = p->next[v];
        if (p->asc) {
            if (cnt < M)
            printf("%c", p->asc);
            cnt ++;
            p = root;
        }
    }
}

bool check(char s[]) {
    int cnt = 0;
    for (int i = 0; i < 8; i++)
        if (s[i] == '1') cnt ++;
    if (s[8] == '1' && !(cnt % 2)) return true;
    if (s[8] == '0' && (cnt % 2)) return true;
    return false;
}

int main() {
    for (int i = 0; i <= 9; i ++)
        strcpy(HTB[48 + i], trans[i]);
    for (int i = 0; i < 6; i ++)
        strcpy(HTB[65 + i], trans[10 + i]);
    for (int i = 0; i < 6; i ++)
        strcpy(HTB[97 + i], trans[16 + i]);
    
    int T;
    scanf("%d", &T);
    while (T --) {
    scanf("%d%d", &M, &N);
    cnt = 0;
    root = (trie*)malloc(sizeof(trie));
    init(root);
    char S[20];
    int asc;
        
    for (int i = 0; i < N; i++) {
        scanf("%d%s", &asc, S);
        insert(S, asc);
    }
    
    scanf("%s", s);
    memset(bin, 0, sizeof(bin));
    memset(data, 0, sizeof(data));
    int ptr = 0;
    for (int i = 0; s[i] != 0; i ++) {
        for (int k = 0; k < 4; k++)
            bin[ptr++] = HTB[s[i]][k];
    }
    
    ptr = 0;
    for (int i = 0; bin[i] != 0; i += 9) {
        if (check(bin + i)) {
            for (int j = 0; j < 8; j++)
                data[ptr++] = bin[i + j];
        }
    }
    
    search(data);
    printf("\n");
    Clear(root);
    }
    return 0;
}

 

                                   Lattice's basics in digital electronics 

LATTICE is learning Digital Electronic Technology. He is talented, so he understood all those pieces of knowledge in 10−9 second. In the next 10−9 second, he built a data decoding device that decodes data encoded with his special binary coding rule to meaningful words.

His coding rule is called "prefix code", a type of code system (typically a variable-length code) distinguished by its possession of the "prefix property", which requires that there is no whole code word in the system that is a prefix (initial segment) of any other code word in the system. Note that his code is composed of only 0 and 1.

LATTICE's device only receives data that perfectly matches LATTICE's rules, in other words,people who send message to LATTICE will always obey his coding rule. However, in the process of receiving data, there are errors that cannot avoid, so LATTICE uses parity check to detect error bytes, after every 8-bit data there is 1 bit called parity bit, which should be '0'

if there are odd number of '1' s in the previous 8 bits and should be '1' if there are even number of '1' s. If the parity bit does not meet the fact, then the whole 9 bits (including the parity bit) should be considered as invalid data and ignored. Data without parity bit is also considered as invalid data. Parity bits will be deleted after the parity check.

For example, consider the given data "101010101010101010101010" , it should be divided into 3parts: "101010101" , "010101010" and "101010" . For the first part, there are 4 '1' s in the first8 bits, and parity bit is '1' , so this part passed the check. For the second part, there are 4

'1' s and parity bit is '0' , so this part failed the check. For the third part, it has less than 9bits so it contains no parity bit, so this part also failed the check. The data after parity check is "10101010" , which is the first 8 bits of first part.

Data passed the parity check will go into a process that decodes LATTICE's code. The process is described in the following example: consider a situation that, "010" represents

'A' and "1011" represents 'B' , if the data after parity check is "01010110101011010010" , it can be divided into "010" + "1011" + "010" + "1011" + "010" + "010" , which means "ABABAA" . LATTICE's device is so exquisite that it can decode all visible characters in the ASCII table .

LATTICE is famous for his Talk show, some reporters have sneaked into his mansion, they stole the data LATTICE to decode in hexadecimal, the coding rule consists of N pairs of corresponding relations from a bit string Si to an ASCII code Ci, and the message length M,they want to peek his privacy so they come to you to write a program that decodes messages that LATTICE receives.

Input

The first line an integer T (T < 35) represents the number of test cases.

Every test case starts with one line containing two integers, M (0 < M ≤ 100000), the number of original characters, and N (1 ≤ N ≤ 256), then N lines, every line contains an integer Ci, and a string Si(0 < ∣Si∣ ≤ 10), means that Si represents Ci, the ASCII code to a visible character and Si only contains '0' or '1' and there are no two numbers i and j thatSi isprefixofSj.

Then one line contains data that is going to be received in hexadecimal. (0 < ∣data∣< 200000).

Output

For each test case, output the decoded message in a new line, the length of the decoded message should be the same with the length of original characters, which means you can stop decoding having outputted M characters. Input guarantees that it will have no less thanM valid characters and all given ASCII codes represent visible characters.

樣例輸⼊

2
15 9
32 0100
33 11
100 1011
101 0110
104 1010
108 00
111 100
114 0111
119 0101 A6Fd021171c562Fde1 83
49 0001
50 01001
51 011 14DB24722698

樣例輸出

hello world!!!!
12332132

題⽬來源

ACM-ICPC 2018 瀋陽賽區網絡預賽

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章