topcoder problem - CircleCount

Problem Statement

Solution by Per  @ topcoder 

#include  < sstream >  
#include 
< algorithm >  
#include 
< cmath >  
#include 
< iostream >  
#include 
< map >  
#include 
< set >  
#include 
< string >  
#include 
< vector >  

using   namespace  std; 

typedef 
long   long  ll; 
typedef pair
< int , int >  pii; 
typedef pair
< double , double >  pdd; 
typedef vector
< int >  vi; 
typedef vector
< string >  vs; 
typedef map
< string , int >  msi; 
typedef unsigned 
int   uint
typedef map
< int uint >  mii; 

int  init1[ 30 ], init2[ 30 ], park1[ 30 ], park2[ 30 ]; 
mii ways; 
int  tot; 

uint  lim  =   2000000000

uint  Ways( int  M) { 
  
if  ( ! M)  return   1
  
uint   & res  =  ways[M]; 
  
if  ( ! res) { 
    
for  ( int  i  =   0 ; ( 1 << i)  <=  M;  ++ i) 
      
if  (M  &  ( 1 << i)) { 
  
if  ( ! (init1[i]  &  M)  &&   ! (park1[i]  &   ~ M)  ||  
      
! (init2[i]  &  M)  &&   ! (park2[i]  &   ~ M)) { 
    res 
+=  Ways(M  &   ~ ( 1 << i)); 
    
if  (res  >  lim) { 
      res 
=  lim + 1
      
break
    } 
  } 
      } 
    
++ res; 
  } 
  
return  res - 1


struct  CircleCount { 
  
int  countOrder( string  circle) { 
    
int  n  =  circle.length(); 
    
int  have  =   0
    
int  free  =   0
    
for  ( int  i  =   0 ; i  <  n;  ++ i) 
      
if  (tolower(circle[i])  ==  circle[i]) { 
  
int  x  =  circle[i] - ' a '
  init1[x] 
=  init2[x]  =  park1[x]  =  park2[x]  =   0
  
for  ( int  j  =   1 ; j  <  n;  ++ j) { 
    
char  c  =  circle[(i + j) % n]; 
    
if  (tolower(c)  ==  circle[i]) 
      
break
    
if  (tolower(c)  ==  c) 
      init1[x] 
|=   1 << (c - ' A ' ); 
    
else  
      park1[x] 
|=   1 << (c - ' A ' ); 
  } 
  
for  ( int  j  =   1 ; j  <  n;  ++ j) { 
    
char  c  =  circle[(i - j + n) % n]; 
    
if  (tolower(c)  ==  circle[i]) 
      
break
    
if  (tolower(c)  ==  c) 
      init2[x] 
|=   1 << (c - ' a ' ); 
    
else  
      park2[x] 
|=   1 << (c - ' A ' ); 
  } 
  
if  ( ! init1[x]  &&   ! park1[x]  ||   ! init2[x]  &&   ! park2[x]) 
    
++ free; 
  
else  
    have 
|=   1 << x; 
      } 
    ways.clear(); 
    ll res 
=  Ways(have); 
    
for  ( int  i  =   0 ; i  <  free;  ++ i) { 
      
if  (res  >  lim)  break
      res 
*=  n / 2 - i; 
    } 
    
if  (res  >  lim) res  =   - 1
    
return  res; 
  } 
   
}; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值