UVA-1052-算法训练-Bit-Compressor


title: UVA-1052-算法训练-Bit Compressor
categories:

  • ACM
  • 高级dfs
    tags:
  • 编码
  • 动态二进制
    date: 2020-03-25 16:23:34

**dfs奥义:不确定性即可能性!并且有时候可能性可以没有顺序!**本文的不确定性在于对于前面有1的0,不确定是分隔符还是二进制中的一部分。这就是不确定性,也就是可能性。本程序还利用了二进制的动态计算。

试题 算法训练 Bit Compressor

提交此题

资源限制

时间限制: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

算法

先说二进制的动态计算,你可能会说我还不会二进制转十进制吗?例如1101,分别计算1,11,110,1101。每一个的前面都是重复的,我们可以用到前面的计算结果,这样可以避免重复计算,提高效率。

dfs参数(要处理的位置下标,已经处理的原串中的字符个数,已经处理的原串中的1的个数)。后两个参数是为了剪枝的。如果碰到前面没有1的0直接跳过,因为肯定是原串中的0,对于每个前面有1的0我们提供两种选择,一是作为原串中的0(把前面的反编码成二进制个1),二是作为二进制中的0。但是这样会出现一个棘手的问题,一是10不能反编码回去,因为反编码得到11,长度都是2,不合题意,你可能说1也不能反编码回去,但是1无论是反编码还是不反编码得到的都是一样的结果,既然这样为什么还认为1不能反编码增加额外代码量呢?也就是说原串中的11是不能编码成10的,所以编码后的串中如果出现11不能确定是原串中的是11还是111,也就是说按照碰到前面有1的0就提供两种可能性的策略,对于10不能进去,对于11少算了一个。对于少算的可以额外增加,因为可能性的顺序没关系。但是对于多算的我们要加条件过滤。于是代码就产生了

#include<stdio.h>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 50
int n,m; 
string s;
int answer=0; 
void dfs(int pos,int len,int len_1){
	if(pos==s.length()&&len==n&&len_1==m)
	{
		answer++;
		return ;
	}
	if(pos>=s.length()||len>n||len_1>m)
	return ;
	if(s[pos]=='0')
	{
		dfs(pos+1,len+1,len_1);
		return ;
	}
	int t=0;
	for(int i=pos;i<s.length();i++)
	{
		t*=2;
		t+=s[i]-'0';
		if(len_1+t>m||len+t>n)
		break;
		if(s[i+1]!='1'&&(t!=2))
			dfs(i+1,len+t,len_1+t);
	}
	if(s[pos+1]=='1'&&s[pos+2]!='1') dfs(pos+2,len+2,len_1+2);
}
int main()
{
	//freopen("input.txt", "r", stdin);
	int e=1;
	while(cin>>n>>m&&n){
		answer=0;
		cin>>s;
		dfs(0,0,0);
		printf("Case #%d: ",e++);
        if(answer==0)
            printf("NO\n");
        else if(answer==1)
            printf("YES\n");
        else
            printf("NOT UNIQUE\n");
	}
    return 0;
}
发布了43 篇原创文章 · 获赞 1 · 访问量 911

猜你喜欢

转载自blog.csdn.net/qq_43985303/article/details/105149948
BIT