109f2a9050 2012-09-08 kinaba: #include <iostream> 109f2a9050 2012-09-08 kinaba: #include <sstream> 109f2a9050 2012-09-08 kinaba: #include <iomanip> 109f2a9050 2012-09-08 kinaba: #include <vector> 109f2a9050 2012-09-08 kinaba: #include <string> 109f2a9050 2012-09-08 kinaba: #include <map> 109f2a9050 2012-09-08 kinaba: #include <set> 109f2a9050 2012-09-08 kinaba: #include <algorithm> 109f2a9050 2012-09-08 kinaba: #include <numeric> 109f2a9050 2012-09-08 kinaba: #include <iterator> 109f2a9050 2012-09-08 kinaba: #include <functional> 109f2a9050 2012-09-08 kinaba: #include <complex> 109f2a9050 2012-09-08 kinaba: #include <queue> 109f2a9050 2012-09-08 kinaba: #include <stack> 109f2a9050 2012-09-08 kinaba: #include <cmath> 109f2a9050 2012-09-08 kinaba: #include <cassert> 109f2a9050 2012-09-08 kinaba: using namespace std; 109f2a9050 2012-09-08 kinaba: typedef long long LL; 109f2a9050 2012-09-08 kinaba: typedef long double LD; 109f2a9050 2012-09-08 kinaba: typedef complex<LD> CMP; 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: template<typename T> 109f2a9050 2012-09-08 kinaba: struct DP2 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: const int N1, N2; 109f2a9050 2012-09-08 kinaba: vector<T> data; 109f2a9050 2012-09-08 kinaba: DP2(int N1, int N2, const T& t = T()) 109f2a9050 2012-09-08 kinaba: : N1(N1), N2(N2), data(N1*N2, t) { assert(data.size()*sizeof(T)<(1<<26)); } 109f2a9050 2012-09-08 kinaba: T& operator()(int i1, int i2) 109f2a9050 2012-09-08 kinaba: { return data[ (i1*N2)+i2 ]; } 109f2a9050 2012-09-08 kinaba: void swap(DP2& rhs) 109f2a9050 2012-09-08 kinaba: { data.swap(rhs.data); } 109f2a9050 2012-09-08 kinaba: }; 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: class MapGuessing { public: 109f2a9050 2012-09-08 kinaba: long long countPatterns(string goal, vector <string> code_) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: string code = accumulate(code_.begin(), code_.end(), string("")); 109f2a9050 2012-09-08 kinaba: deque<char> pattern(1, '?'); 109f2a9050 2012-09-08 kinaba: int head = 0; 109f2a9050 2012-09-08 kinaba: for(int i=0; i<code.size(); ++i) 109f2a9050 2012-09-08 kinaba: switch(code[i]) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: case '0': 109f2a9050 2012-09-08 kinaba: case '1': 109f2a9050 2012-09-08 kinaba: pattern[head] = code[i]; 109f2a9050 2012-09-08 kinaba: break; 109f2a9050 2012-09-08 kinaba: case '<': 109f2a9050 2012-09-08 kinaba: head--; 109f2a9050 2012-09-08 kinaba: if(head==-1) { 109f2a9050 2012-09-08 kinaba: head = 0; 109f2a9050 2012-09-08 kinaba: pattern.push_front('?'); 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: break; 109f2a9050 2012-09-08 kinaba: case '>': 109f2a9050 2012-09-08 kinaba: head++; 109f2a9050 2012-09-08 kinaba: if(head==pattern.size()) 109f2a9050 2012-09-08 kinaba: pattern.push_back('?'); 109f2a9050 2012-09-08 kinaba: break; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: return solve(goal, string(pattern.begin(), pattern.end())); 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: LL solve(const string& G, const string& P) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: if(P.size() > G.size()) 109f2a9050 2012-09-08 kinaba: return 0; 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: int N = P.size(); 109f2a9050 2012-09-08 kinaba: vector< vector<int> > DFA(N, vector<int>(2)); 109f2a9050 2012-09-08 kinaba: for(int i=0; i<N; ++i) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: int fail = 0; 109f2a9050 2012-09-08 kinaba: for(int k=i-1; k>=0; --k) 109f2a9050 2012-09-08 kinaba: if( match(P.substr(0, k), P.substr(i-k, k)) 109f2a9050 2012-09-08 kinaba: && match(P[k], nega(P[i])) ) { 109f2a9050 2012-09-08 kinaba: fail = k; 109f2a9050 2012-09-08 kinaba: break; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: if(P[i]=='0') 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: DFA[i][0] = i+1; 109f2a9050 2012-09-08 kinaba: DFA[i][1] = fail; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: else if(P[i]=='1') 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: DFA[i][0] = fail; 109f2a9050 2012-09-08 kinaba: DFA[i][1] = i+1; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: else 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: DFA[i][0] = i+1; 109f2a9050 2012-09-08 kinaba: DFA[i][1] = i+1; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: LL total = 0; 109f2a9050 2012-09-08 kinaba: for(int s=0; s+P.size()<=G.size(); ++s) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: LL v = subProblem(s, G, s+P.size(), DFA, N); 109f2a9050 2012-09-08 kinaba: total += v; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: return total; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: char nega(char c) { return c=='?' ? c : c=='0' ? '1' : '0'; } 109f2a9050 2012-09-08 kinaba: bool match(char a, char b) { 109f2a9050 2012-09-08 kinaba: return a=='?' || b=='?' || a==b; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: bool match(const string& a, const string& b) { 109f2a9050 2012-09-08 kinaba: for(int i=0; i<a.size(); ++i) 109f2a9050 2012-09-08 kinaba: if(!match(a[i], b[i])) 109f2a9050 2012-09-08 kinaba: return false; 109f2a9050 2012-09-08 kinaba: return true; 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: LL subProblem(int s, const string& G, int M, const vector< vector<int> >& DFA, int Q) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: DP2<LL> dp(M+1, Q+1); 109f2a9050 2012-09-08 kinaba: dp(0, 0) = 1; 109f2a9050 2012-09-08 kinaba: for(int i=0; i<M; ++i) 109f2a9050 2012-09-08 kinaba: for(int q=0; q<Q; ++q) 109f2a9050 2012-09-08 kinaba: { 109f2a9050 2012-09-08 kinaba: if(s>=i || G[i]=='0') 109f2a9050 2012-09-08 kinaba: dp(i+1, DFA[q][0]) += dp(i,q); 109f2a9050 2012-09-08 kinaba: if(s>=i || G[i]=='1') 109f2a9050 2012-09-08 kinaba: dp(i+1, DFA[q][1]) += dp(i,q); 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: return dp(M, Q); 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: }; 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: // BEGIN CUT HERE 109f2a9050 2012-09-08 kinaba: #include <ctime> 109f2a9050 2012-09-08 kinaba: double start_time; string timer() 109f2a9050 2012-09-08 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 109f2a9050 2012-09-08 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 109f2a9050 2012-09-08 kinaba: { os << "{ "; 109f2a9050 2012-09-08 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 109f2a9050 2012-09-08 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 109f2a9050 2012-09-08 kinaba: void verify_case(const long long& Expected, const long long& Received) { 109f2a9050 2012-09-08 kinaba: bool ok = (Expected == Received); 109f2a9050 2012-09-08 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 109f2a9050 2012-09-08 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 109f2a9050 2012-09-08 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 109f2a9050 2012-09-08 kinaba: #define END verify_case(_, MapGuessing().countPatterns(goal, code));} 109f2a9050 2012-09-08 kinaba: int main(){ 109f2a9050 2012-09-08 kinaba: 109f2a9050 2012-09-08 kinaba: CASE(0) 109f2a9050 2012-09-08 kinaba: string goal = "000"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"0"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 4LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(1) 109f2a9050 2012-09-08 kinaba: string goal = "001"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"0>1"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 5LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(2) 109f2a9050 2012-09-08 kinaba: string goal = "000"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"1>1>1"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 1LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(3) 109f2a9050 2012-09-08 kinaba: string goal = "11001"; 109f2a9050 2012-09-08 kinaba: string code_[] = {">><<<<><<"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 0LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(4) 109f2a9050 2012-09-08 kinaba: string goal = "1000101011"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"1<<0>>0>1"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 22LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(5) 109f2a9050 2012-09-08 kinaba: string goal = "00000010000000000000000000000000"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"><>>0<0<>>1>0><>", "<<0>>0<>><0>0>>><><", ">>>0<>", ">0><>>>>0<<><>>0>>>0<0>>0>"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 13601LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(6) 109f2a9050 2012-09-08 kinaba: string goal = "11100011010111111010100100110001101"; 109f2a9050 2012-09-08 kinaba: string code_[] = {"11111111111111111111" 109f2a9050 2012-09-08 kinaba: ,"1<><><><><><><><><>1" 109f2a9050 2012-09-08 kinaba: ,"1<>000>000><0<><0<>1" 109f2a9050 2012-09-08 kinaba: ,"1<0<><>0><0<00>00<>1" 109f2a9050 2012-09-08 kinaba: ,"1<>00<>000><0<0<0<>1" 109f2a9050 2012-09-08 kinaba: ,"1<><>0>0><0<0<><0<>1" 109f2a9050 2012-09-08 kinaba: ,"1<000<>0><0<0<><0<>1" 109f2a9050 2012-09-08 kinaba: ,"1<><><><><><><><><>1" 109f2a9050 2012-09-08 kinaba: ,"1<>000><000<>000><>1" 109f2a9050 2012-09-08 kinaba: ,"1<>0><><0<><>0><><>1" 109f2a9050 2012-09-08 kinaba: ,"1<>000><000<>000><>1" 109f2a9050 2012-09-08 kinaba: ,"1<><>0><><0<><>0><>1" 109f2a9050 2012-09-08 kinaba: ,"1<>000><000<>000><>1" 109f2a9050 2012-09-08 kinaba: ,"1<><><><><><><><><>1" 109f2a9050 2012-09-08 kinaba: ,"11111111111111111111"}; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = 90LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: /* 109f2a9050 2012-09-08 kinaba: CASE(7) 109f2a9050 2012-09-08 kinaba: string goal = ; 109f2a9050 2012-09-08 kinaba: string code_[] = ; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: CASE(8) 109f2a9050 2012-09-08 kinaba: string goal = ; 109f2a9050 2012-09-08 kinaba: string code_[] = ; 109f2a9050 2012-09-08 kinaba: vector <string> code(code_, code_+sizeof(code_)/sizeof(*code_)); 109f2a9050 2012-09-08 kinaba: long long _ = LL; 109f2a9050 2012-09-08 kinaba: END 109f2a9050 2012-09-08 kinaba: */ 109f2a9050 2012-09-08 kinaba: } 109f2a9050 2012-09-08 kinaba: // END CUT HERE