UVa213

213 Message Decoding
Some message encoding schemes require that an encoded message be sent in two parts. The first part,
called the header, contains the characters of the message. The second part contains a pattern that
represents the message. You must write a program that can decode messages under such a scheme.
The heart of the encoding scheme for your program is a sequence of “key” strings of 0’s and 1’s as
follows:
0; 00; 01; 10; 000; 001; 010; 011; 100; 101; 110; 0000; 0001; : : : ; 1011; 1110; 00000; : : :
The first key in the sequence is of length 1, the next 3 are of length 2, the next 7 of length 3, the
next 15 of length 4, etc. If two adjacent keys have the same length, the second can be obtained from
the first by adding 1 (base 2). Notice that there are no keys in the sequence that consist only of 1’s.
The keys are mapped to the characters in the header in order. That is, the first key (0) is mapped
to the first character in the header, the second key (00) to the second character in the header, the kth
key is mapped to the kth character in the header. For example, suppose the header is:
AB#TANCnrtXc
Then 0 is mapped to A, 00 to B, 01 to #, 10 to T, 000 to A, ..., 110 to X, and 0000 to c.
The encoded message contains only 0’s and 1’s and possibly carriage returns, which are to be ignored.
The message is divided into segments. The first 3 digits of a segment give the binary representation of
the length of the keys in the segment. For example, if the first 3 digits are 010, then the remainder of
the segment consists of keys of length 2 (00, 01, or 10). The end of the segment is a string of 1’s which is
the same length as the length of the keys in the segment. So a segment of keys of length 2 is terminated
by 11. The entire encoded message is terminated by 000 (which would signify a segment in which the
keys have length 0). The message is decoded by translating the keys in the segments one-at-a-time into
the header characters to which they have been mapped.
Input
The input file contains several data sets. Each data set consists of a header, which is on a single line by
itself, and a message, which may extend over several lines. The length of the header is limited only by
the fact that key strings have a maximum length of 7 (111 in binary). If there are multiple copies of a
character in a header, then several keys will map to that character. The encoded message contains only
0’s and 1’s, and it is a legitimate encoding according to the described scheme. That is, the message
segments begin with the 3-digit length sequence and end with the appropriate sequence of 1’s. The keys
in any given segment are all of the same length, and they all correspond to characters in the header.
The message is terminated by 000.
Carriage returns may appear anywhere within the message part. They are not to be considered as
part of the message.
Output
For each data set, your program must write its decoded message on a separate line. There should not
be blank lines between messages.
Universidad de Valladolid OJ: 213 – Message Decoding 2/2
Sample input
TNM AEIOU
0010101100011
1010001001110110011
11000
$#**\
0100000101101100011100101000
Sample output
TAN ME
##*\$

题意:

题目要求是根据二进制密码输出其对应的信息。编码方式是这样的:长度为1到7的二进制码都有可能对应一个字符,但是各长度的二进制密码都不包括仅包含‘1’的那些二进制码(比如‘1’、‘11’、‘111’);首先输入一列不包含换行的字符串,我们从左至右依次读取字符串的每一个字符并对其进行编码,从左至右第1个编码为‘0’、第2个为‘00’、第3个为‘01’、第4个为‘000’、第5个为‘001’,依次类推,即当编码长度相同的时候,后一个编码总是前一个编码在二进制下对应加1的那个数(with leading zeros),二进制码长度不会超过7。下面一行输入的就是由‘0’和‘1’组成的字符串。开始的三个‘0’、‘1’串在二进制下代表0~7的一个整数,意味着它之后的那些二进制编码将会以该整数长度进行依次读取并输出相应编码对应的字符,如果该整数为零,则代表该组输入结束。或者读取到全为‘1’的编码,也代表该组数据输入结束。

输入:

多组数据,每组数据第一行为一字符串,用于编码。之后的一行或者数行是二进制密码。

输出:

每组数据输出二进制密码对应的字符串。

分析:

模拟题。书写几个函数将有利于模拟这个过程。用code[len][val]来存储长度为len、二进制对应的十进制值为val的二进制编码对应的字符。readChar()函数将读取下一个非换行字符。readInt(int c)函数将用于读取长度为c的二进制并将其转化为十进制整数(中间忽略换行)。readCodes函数用于编码。

 1 #include <stdio.h>
 2 #include <string.h>
 3
 4 // 编码数组
 5 // [len][value]
 6 int code[8][1<<8];
 7 int readChar() {
 8     while(true) {
 9         int ch = getchar();
10         // 读到非换行符为止
11         if(ch != ‘\n‘ && ch != ‘\r‘) {
12             return ch;
13         }
14     }
15 }
16
17 int readInt(int c) {
18     int v = 0;
19     // 获取十进制整数
20     while(c--) {
21         v = v * 2 + readChar() - ‘0‘;
22     }
23     return v;
24 }
25
26 int readCodes() {
27     memset(code, 0, sizeof(code));
28     // 读取编码头的第一个字符
29     code[1][0] = readChar();
30     // 从第二个字符开始循环编码
31     for(int len = 2; len <= 7; len++) {
32         for(int i = 0; i < (1 << len) - 1; i++) {
33             int ch = getchar();
34             // 文件结束,终止程序
35             if(ch == EOF) {
36                 return 0;
37             }
38             // 读一行
39             if(ch == ‘\n‘ || ch == ‘\r‘) {
40                 return 1;
41             }
42             code[len][i] = ch;
43         }
44     }
45     return 1;
46 }
47
48 int main() {
49     while(readCodes()) {
50         while(true) {
51             // 读入编码长度
52             int len = readInt(3);
53             // 长度为0退出当前编码循环
54             if(!len) break;
55             while(true) {
56                 int v = readInt(len);
57                 // 全为1退出当前小节
58                 if(v == (1 << len) - 1) break;
59                 putchar(code[len][v]);
60             }
61         }
62         putchar(‘\n‘);
63     }
64     return 0;
65 }

时间: 2024-10-17 19:33:16

UVa213的相关文章

UVA213 UVALive5152 Message Decoding

World Finals >> 1991 - San Antonio 问题链接:UVA213 UVALive5152 Message Decoding. 问题简述:参见问题链接. 问题分析:(略). 程序中,若干功能封装到函数中,使得程序逻辑变得简洁. AC的C语言程序如下: /* UVA213 UVALive5152 Message Decoding */ #include <stdio.h> #include <memory.h> #define CODE_LEN

紫书第一章训练1 D -Message Decoding(UVA213) by 16黄睿博

来源:http://m.blog.csdn.net/article/details?id=70766751 Some message encoding schemes require that an encoded message be sent in two parts. The ?rst part, called the header, contains the characters of the message. The second part contains a pattern tha

UVA213 Message Descoding

#include <iostream> #include <string.h> char code[8][1 << 8], s[1 << 8]; using namespace std; // 过滤空行,返回字符串长度 int my_gets(char* s) { int k; //读入s列 while ((cin>>k) &&k== '\n'); // 空行重读 if (k == -1) k = 0; else gets(s +

UVA213信息解码

<算法竞赛入门经典>第四章函数和递归中的题目,考察了自定义函数应用和二进制相关内容.(个人认为考察二进制相关知识占多). 题意:给一个编码头和一串编码(编码可以换行),编码头根据以下规则对应编码{  考虑下面的01串:  0,00,01,10,000,001,010,101,110,0000,0001.....首先是长度为1的串,然后是长度为二的串,以此类推.并且每一段长度的数字从0到(1<<n)-1(第n段)排列,即题目中所说不包括全为1的串. 编码文本由多个小节组成,每小节前三

[算法竞赛入门经典]Message Decoding,ACM/ICPC World Finals 1991,UVa213

Description Some message encoding schemes require that an encoded message be sent in two parts. The first part, called the header, contains the characters of the message. The second part contains a pattern that represents the message. You must write

算法习题---4.4信息解码(UVa213)

一:题目 消息编码方案要求在两个部分中发送一个被编码的消息.第一部分:称为头,包含消息的字符.第二部分包含一个模式 表示信息.你必须写一个程序,可以解码这个消息. (一)题目详细 你的程序的编码方案的核心是一个序列的“0和1”的字符串 . 0, 00, 01, 10, 000, 001, 010, 011, 100, 101, 110, 0000, 0001, . . . , 1011, 1110, 00000, . . .(对应数字个数n,则表示的编码为2^n-1个) 序列中长度为1的1个,长

刷题记录--UVa213 Message Decoding

紫书上的思路我觉得很不错,尤其是数据存储和调用的方式,值得学习. 下面的码是我看了之后自己独立完成了,但也废了不少功夫. 未注意格式,也没有submit,可能会wa,但结果应该是正确的. #include<cstdio> //#define LOCAL #include<cstring> #include<iostream> using namespace std; int code[8][1<<8]; int readchar(void){ for(;;)

算法练习(一)

昨天是个值得纪念的日子,我数学建模拿了推荐国家一等奖的名额,希望最后能顺利拿到国一吧.现在大三已经开学一个月了.这一个月因为社会实践评优的事情真的很忙,还好最后拿到了可能拿到的所有的奖项.结果自己把科研助手这件事给耽误了,今天去找马老师,结果马老师的实验室人已经满了.所以没办法,我可能又要去找其他老师了. 今年国家奖学金的名额里面没有我,没有就算了吧.卧薪尝胆,好好学习,这一学期至关重要.所以自己现在就要开始准备保研的机试,现在的训练非常重要,无论如何,这是自己未来要走的一步路.我现在最重要的就

UVA - 213解题报告

题目链接:https://cn.vjudge.net/problem/UVA-213 Sample input TNM AEIOU 0010101100011 1010001001110110011 11000 $#**\ 0100000101101100011100101000 Sample output TAN ME ##*\$ 题目思想: 1.先把输入的编码按照0, 00,01, 10,000, 001,010, 011,100, 101, 110,0000, 0001,.-,1011,