前缀码:任何一个字符的编码都不是同一字符集中另一个字符的编码的前缀。
请编写一个程序,判断输入的n个由1和0组成的编码是否为前缀码。如果这n个编码是前缀码,则输出"YES”;否则输出第一个与前面编码发生矛盾的编码。
输入:
第1行为n(表示下面有n行编码)
第2~n+1行为n个由0或1组成的编码
输出:判断结果
例如,如果输入:
5
00
01
10
110
111
每一个字符均不是其他字符编码的前缀,所以,输出:YES
再如,如果输入:
5
00
01
10
110
11
编码11与前面的编码110的前缀,所以,输出:11
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 2 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 3 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 4 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 5 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 6 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
代码如下:
比较简单注释就只写了下思路,其实就是哈夫曼树,以后应该要学。也有可能是我上课睡觉听漏了,说不定已经教了。
需要注意为假的判定。
也可以用数组写。
/*
Huffman Tree(哈夫曼树),树干即编码,路径长度即编码长度.
根据二叉树特性通过树干路径进行编码(左分支赋予0,右分支赋予1).
构成前缀编码的形式,即一组编码中任一编码都不是其他任何一个编码的前缀.
那么这道题也就是考虑根据编码能否还原出一个哈夫曼树的问题,
如果能还原出一个哈夫曼树,那么就是一组编码中任一编码都不是其他任何一个编码的前缀
*/
#include <iostream>
#include <string>
using namespace std;
struct HFTree
{
bool flag;
HFTree *left;
HFTree *right;
HFTree() : flag(false), left(nullptr), right(nullptr) {}
};
bool isPrefixCode(const string &str, HFTree *&root)
{
HFTree *Root = root;
for (char ch : str)
{
if (ch == '0')
{
if (Root->left == nullptr)
Root->left = new HFTree;
Root = Root->left;
if (Root->flag)
return false;
}
else
{
if (Root->right == nullptr)
Root->right = new HFTree;
Root = Root->right;
if (Root->flag)
return false;
}
}
Root->flag = true;
return !Root->left && !Root->right;
}
int main()
{
int n;
cin >> n;
HFTree *root= new HFTree;
while (n--)
{
string str;
cin >> str;
if (!isPrefixCode(str, root))
{
cout << str << endl;
return 0;
}
}
cout << "YES" << endl;
return 0;
}