蓝桥杯练习 | Bit Compressor

问题描述

数据压缩的目的是为了减少存储和交换数据时出现的冗余。这增加了有效数据的比重并提高了传输速率。有一种压缩二进制串的方法是这样的:
将连续的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;
} 
上一篇:SQL 表的知识


下一篇:mysql分区表存在唯一索引时,唯一索引为什么必须包含所有分区字段