Move Google Code Jam under puzzles.
This commit is contained in:
230
puzzles/google_code_jam/2014/1C-B.cpp
Normal file
230
puzzles/google_code_jam/2014/1C-B.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/* Check cf5-opt.vim defs.
|
||||
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
|
||||
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
|
||||
VIM: let g:cppflags=g:Iboost.g:Itbb
|
||||
VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
|
||||
VIM: let g:ldlibpath=g:Bboost.g:Btbb
|
||||
VIM: let g:argv=""
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
|
||||
typedef long long ll;
|
||||
typedef std::vector<ll> vec;
|
||||
void check( bool b ) { if ( !b )
|
||||
std::cerr << "error" << std::endl; }
|
||||
#define FOR(i,l) for ( ll i =0, ie = ll(l); i<ie; ++i )
|
||||
/*
|
||||
Read n values into v
|
||||
*/
|
||||
template <class V>
|
||||
void readv( V& v, int n )
|
||||
{
|
||||
v.reserve(n);
|
||||
for ( int i = 0; i < n; ++i )
|
||||
{
|
||||
typename V::value_type e;
|
||||
std::cin >> e;
|
||||
check( !std::cin.fail() );
|
||||
v.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
template <class V>
|
||||
ll perm( V& v, size_t idx = 0 )
|
||||
{
|
||||
std::vector<int> p(26,0);
|
||||
char c = 0;
|
||||
for ( int j = 0; j < idx+1; ++j )
|
||||
{
|
||||
for( auto l : v[j] )
|
||||
{
|
||||
if ( c != l )
|
||||
{
|
||||
if ( p[ l-'a' ] )
|
||||
return 0;
|
||||
else
|
||||
p[ l-'a' ] = 1;
|
||||
c = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( idx == v.size()-1 )
|
||||
return 1;
|
||||
|
||||
ll r = 0;
|
||||
for( size_t i = idx; i < v.size(); i++ )
|
||||
{
|
||||
std::swap(v[idx],v[i]);
|
||||
r += perm<V>(v,idx+1);
|
||||
std::swap(v[idx],v[i]);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class V, class S>
|
||||
bool remove_group( V& s, int a, S& rc )
|
||||
{
|
||||
int c = a;
|
||||
for ( auto jt = s.begin(); jt != s.end(); )
|
||||
{
|
||||
if ( (*jt)[0] == c )
|
||||
{
|
||||
for( auto l : *jt )
|
||||
{
|
||||
if ( c != l )
|
||||
{
|
||||
if ( rc.find(l) != rc.end() )
|
||||
return false;
|
||||
else
|
||||
{
|
||||
rc.insert(l);
|
||||
c = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
jt = s.erase(jt);
|
||||
}
|
||||
else
|
||||
++jt;
|
||||
}
|
||||
c = a;
|
||||
for ( auto jt = s.begin(); jt != s.end(); )
|
||||
{
|
||||
if ( (*jt).back() == c )
|
||||
{
|
||||
for( auto i = jt->size()-1; i >= 0; --i )
|
||||
{
|
||||
int l = (*jt)[i];
|
||||
if ( c != l )
|
||||
{
|
||||
if ( rc.find(l) != rc.end() )
|
||||
return false;
|
||||
else
|
||||
{
|
||||
rc.insert(l);
|
||||
c = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
jt = s.erase(jt);
|
||||
}
|
||||
else
|
||||
++jt;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ll solve_puzzle()
|
||||
{
|
||||
int n;
|
||||
std::cin >> n;
|
||||
|
||||
const ll m = 1000000007;
|
||||
|
||||
std::vector<std::string> s;
|
||||
readv(s,n);
|
||||
|
||||
std::vector<int> p(26,0);
|
||||
for ( auto it = s.begin(); it != s.end(); )
|
||||
{
|
||||
bool b = true;
|
||||
char c = (*it)[0];
|
||||
for( auto l : *it )
|
||||
{
|
||||
if ( c != l )
|
||||
{
|
||||
b = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( b )
|
||||
{
|
||||
p[c-'a']++;
|
||||
it = s.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
ll coef = 1;
|
||||
for ( int i = 0; i < p.size(); ++i )
|
||||
{
|
||||
auto r = p[i];
|
||||
while( r > 1 )
|
||||
coef *= r--;
|
||||
}
|
||||
|
||||
std::set<char> rc;
|
||||
|
||||
int g = 0;
|
||||
for ( int i = 0; i < p.size(); ++i )
|
||||
{
|
||||
if ( p[i] > 0 && rc.find(i+'a') == rc.end() )
|
||||
{
|
||||
g++;
|
||||
if ( !remove_group( s, i+'a', rc ) )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while ( s.size() )
|
||||
{
|
||||
g++;
|
||||
if ( !remove_group( s, s.front().front(), rc ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
ll i = 1;
|
||||
while ( g > 1 )
|
||||
i *= g--;
|
||||
|
||||
return (i*coef)%m;
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{try{
|
||||
srand((unsigned)time(NULL));
|
||||
int puzzle_count;
|
||||
|
||||
std::cin >> puzzle_count;
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
|
||||
for ( int i = 1; i <= puzzle_count; i++ )
|
||||
{
|
||||
std::cout << "Case #" << i << ": ";
|
||||
auto r = solve_puzzle();
|
||||
std::cout << r << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
||||
return 2;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "unknown exception." << std::endl;
|
||||
return 1;
|
||||
}}
|
||||
Reference in New Issue
Block a user