资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
数据压缩的目的是为了减少存储和交换数据时出现的冗余。这增加了有效数据的比重并提高了传输速率。有一种压缩二进制串的方法是这样的:
将连续的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
题解:直接深度搜索,如果开头为0,直接下一层搜索,如果为1,判断下后面的字符串构成的数字然后再下一层搜索判断是否成立,累加数目判断就行。
代码
#include<bits/stdc++.h>
using namespace std;
int ans;
string s;
int Binary_length(int x)
{
int ans=0;
while(x>0)
{
ans++;
x/=2;
}
return ans;
}
void dfs(int L,int N,int x)
{
//保证3个元素都被用完
if(L==0&&N==0&&x==s.length())
{
ans++;
return;
}
if(L<0||N<0)return;
//0不能组成压缩状态,直接下一层,然后长度减1
if(s[x]=='0')
{
dfs(L-1,N,x+1);
}
else
{
//sum表示组成的二进制数据,number1表示x到i之间1的个数
int sum=0,number1=0;
for(int i=x;i<s.length();i++)
{
if(s[i]=='1')
number1++;
sum*=2;
sum+=(s[i]-'0');
//如果是压缩的结果,那么右边肯定不能为1,因为连续的1会一起被压缩
if(s[i+1]=='1')continue;
if(sum>(i-x+1))
{
dfs(L-sum,N-sum,i+1);
}
//判断这个地方是否可能是原串没有处理保留下来的
//这里有两种情况,比如字符串10,10会被程序分解为1和0单独判断
//或者10一起判断,都是成立,但是这样会累加两次,我们直接考虑
//10这种不全为1的情况,就单独1和0判断,否则都为1,比如11,就一起判断
//不是单独的,但是不全为1,跳过
if(i!=x&&number1!=(i-x+1))continue;
int ans=Binary_length(i-x+1);
if(ans==(i-x+1))
{
dfs(L-(i-x+1),N-number1,i+1);
}
}
}
}
int main()
{
int L,N;
while(cin>>L>>N>>s)
{
ans=0;
dfs(L,N,0);
if(ans==1)
puts("YES");
else if(ans>=2)
puts("NOT UNIQUE");
else puts("NO");
}
return 0;
}

5万+

被折叠的 条评论
为什么被折叠?



