题目描述:
题目大意:
有一些串: 0,00,01,10,000,001,010,011,100,101,110,0000,0001,…,1101,1110,00000,…首先是长度为1的串 ,然后是长度为2的串,以此类推,相同长度的后一个串等于前一个串加1,而且不存在全为1的串。
首先输入一个编码头 , 比如 ABCD,那么依次对应上面的01串,比如0对应A,00对应B,01对应C,000对应D,接下来输入编码文本,编码文本由多个小节组成,每一个小节中的前3个数字代表小节中每个编码的长度,根据长度来进行各个字符的编码,对应上面的编码头,以全1结束。编码文本以编码长度为000的小节结束。
举个例子:比如编码头为ABCD,编码文本为0100000101101100011100101000
则010(编码长度2)00(B)00(B)10(C)11(小节结束)011(编码长度3)000(D)111(小节结束)001(编码长度1)0(A)1(小节结束)000(编码结束)
分析:采用一边输入一边保存对应编码头,编码的时候也是一边输入一边编码。
#include<cstdio>
#include<cstring>
using namespace std;
char code[8][1<<8];
/*读取字符,可跨行*/
int readchar()
{
for(;;)
{
int ch = getchar();
if(ch != '\n' && ch != '\r')
return ch;
}
}
/*读取编码头,打到表中*/
int readcodes()
{
memset(code, 0, sizeof(code));
code[1][0] = readchar();
for(int len=2; len<=7; len++)
{
for(int i=0; i<(1<<len)-1; i++)
{
int ch = getchar();
if(ch == EOF) return 0;
if(ch == '\n' || ch == '\r') return 1;
code[len][i] = ch;
}
}
return 1;
}
/*读取c位二进制数,并转换为10进制返回*/
int readint(int c)
{
int v = 0;
while(c--)
{
v = 2*v + readchar() - '0';
}
return v;
}
/*调试所用*/
void printcodes()
{
for(int len=1; len<=7; len++)
{
for(int i=0; i<(1<<len)-1; i++)
{
if(code[len][i] == 0) return;
printf("code[%d][%d] = %c\n",len, i, code[len][i]);
}
}
}
int main()
{
// freopen("input.txt", "r", stdin);
while(readcodes())
{
// printcodes();
for(;;)
{
int len = readint(3);
if(len == 0) break;
for(;;)
{
int v = readint(len);
if(v == (1<<len)-1) break;
putchar(code[len][v]);
}
}
putchar('\n');
}
return 0;
}