蓝桥杯 试题 算法训练 ALGO-213 Bit Compressor--DFS深度搜索

资源限制
时间限制: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值