This one seems to be a nice backtracking problem, and this is my code. Anyone has an idea on why it gets WA?
Code: Select all
/*
* 1052. Bit Compressor
* m: the length of the original message
* n: the number of 1's in the original message
*/
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { NO, YES, NOT_UNIQUE };
typedef unsigned long long u64;
typedef long long i64;
i64 ts,m,n;
char buff[1<<21];
int f( char *s, i64 m, i64 n ) {
int i,j,k,t,success_01 = 0,ii = -1,jj,
success_02 = 0,
status;
i64 ax;
if ( !*s ) {
if ( !m && !n )
return YES;
return NO;
}
if ( n < 0 || m < 0 )
return NO;
if ( !m )
return NO;
if ( !n ) {
for ( k = 0, i = 0; s[i] == '0' && k < m; ++i, ++k );
if ( s[i] == '1' )
return NO;
if ( k == m && s[m] )
return NO;
assert( !s[i] );
return k == m ? YES:NO;
}
for ( i = 0; s[i]; i = j ) {
for ( j = i; s[j] == '0'; ++j );
if ( !s[j] ) break ;
for ( t = j, k = 1; s[++j] == '1' && ++k; );
if ( k >= 3 ) {
ii = t, jj = j-1;
assert( jj-ii+1 == k );
break ;
}
}
if ( ii != -1 ) {
for ( k = t = 0, i = 0; i < ii; t += (int)(s[i++]-'0'), ++k );
for ( ax = s[i=ii]-'0', j = i+1; s[j]; ++j ) {
ax <<= 1, ax += ((i64)(s[j]-'0'));
if ( s[j+1] == '1' )
continue ;
if ( ax > (j-i+1) ) {
if ( NOT_UNIQUE == (status = f(s+j+1,m-k-ax,n-t-ax)) )
return NOT_UNIQUE;
if ( status == YES && (++success_01) >= 2 )
return NOT_UNIQUE;
}
}
return success_01==1?YES:NO;
}
assert( ii == -1 );
for ( k = t = 0, i = 0; s[i]; t += (int)(s[i++]-'0'), ++k )
if ( (ax = s[i]-'0') && !(i >= 1 && s[i-1] == '1') ) {
for ( j = i+1; s[j]; ++j ) {
ax <<= 1, ax += (i64)(s[j]-'0');
if ( s[j+1] == '1' )
continue ;
if ( (j-i+1) < ax ) {
if ( NOT_UNIQUE == (status = f(s+j+1,m-k-ax,n-t-ax)) )
return NOT_UNIQUE;
if ( status == YES && (++success_01) >= 2 )
return NOT_UNIQUE;
}
}
}
if ( n == t && m == k )
return !success_01 ? YES:NOT_UNIQUE;
return success_01==1?YES:NO;
}
int main() {
int res,i,j,k;
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif
while ( 2 == scanf("%lld %lld",&m,&n) && (m||n) ) {
scanf("%s",buff), printf("Case #%lld: ",++ts);
for ( i = 0; !isdigit(buff[i]); ++i );
for ( k = i; buff[k] && isdigit(buff[k]); ++k );
buff[k] = '\0';
if ( NO == (res = f(buff+i,m,n)) )
puts("NO");
else if ( res == NOT_UNIQUE )
puts("NOT UNIQUE");
else puts("YES");
}
return 0;
}