问题描述
数据压缩的目的是为了减少存储和交换数据时出现的冗余。这增加了有效数据的比重并提高了传输速率。有一种压缩二进制串的方法是这样的:
将连续的n个1替换为n的二进制表示(注:替换发生当且仅当这种替换减少了二进制串的总长度)
(译者注:连续的n个1的左右必须是0或者是串的开头、结尾)
比如:11111111001001111111111111110011会被压缩成10000010011110011。原串长为32,被压缩后串长为17.
这种方法的弊端在于,有时候解压缩算法会得到不止一个可能的原串,使得我们无法确定原串究竟是什么。请你写一个程序来判定我们能否利用压缩后的信息来确定原串。给出原串长L,原串中1的个数N,以及压缩后的串。
L<=16 Kbytes,压缩后的串长度<=40 bits。
输入格式
第一行两个整数L,N,含义同问题描述
第二行一个二进制串,表示压缩后的串
输出格式
输出 "YES" 或 "NO" 或 "NOT UNIQUE"(不包含引号)
分别表示:
YES:原串唯一
NO:原串不存在
NOT UNIQUE:原串存在但不唯一
样例输入
样例1:
32 26
10000010011110011
样例2:
9 7
1010101
样例3:
14 14
111111
样例输出
样例1:YES
样例2:NOT UNIQUE
样例3:NO
————————————————————————————————————————————————————————
代码如下
#include <bits/stdc++.h>
#define MAXN 233
using namespace std;
struct node { int p,l,n,v; };
queue<node> Q;
int l,n,len,ans; char v[MAXN];
inline int fun(int s,int t) {
int ret=1;
for (int i=s+1;i<=t;i++) {
if (v[i]=='1') ret=(ret<<1)+1;
else ret<<=1;
}
return ret;
}
int main() {
scanf("%d%d%s",&l,&n,v+1),len=(int)strlen(v+1);
Q.push((node){0,0,0,0});
while (!Q.empty()) {
node now=Q.front(); Q.pop();
while (v[now.p+1]=='0' && now.p<len) now.p++,now.l++,now.v=0;
if (now.p==len && now.l==l && now.n==n) { ans++; continue; }
for (int i=now.p+1;!now.v && i<=len;i++) {
int t=fun(now.p+1,i); // Add -> [now.p+1,i]
if (now.l+t<=l && now.n+t<=n) Q.push((node){i,now.l+t,now.n+t,1});
}
}
if (ans==1) puts("YES");
else puts(ans?"NOT UNIQUE":"NO");
return 0;
}