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;
}
};
#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;
}
};