This one took more time than Problem 1 and Problem 2, but at least I actually finished this Problem 3, unlike the last few ones.
scode.cpp
#include <iostream> #include <fstream> #define loopi(x) loop_start(i,x,0) #define loopj(x) loop_start(j,x,0) #define loop_start(i,x,s) for(int i = (s); i < (x); ++i) #define loop_rev(a,x,stop) for(int a = (x); a >= (stop); --a) using namespace std; inline bool is_repeated(const char *str1, const char *str2, size_t len) { // There are no NULL characters to worry about return !strncmp(str1, str2, len); /* // old code: while(len--) if(*str1++ != *str2++) return false; return true; */ } /* (s = F_L) may become: Drop L: F_ + s or s + F_ Drop F: _L + s or s + _L F_F_L F_LF_ _LF_L F_L_L But F_ or _L cannot be distinguished, so A_A_L A_LA_ A_FA_ FA_A_ F and L cannot be distinguished either, so A_A_B BA_A_ A_BA_ (x2) */ int sources(char *start, size_t sz) { /* 1. Any string of length L will be encrypted to length (2L-1), which is always (even-1), which is odd. 2. A string of length two is in minimal form. */ if((sz & 1) == 0 || sz <= 2) return 0; int ret = 0; const int sublen = (sz - 1) >> 1; // length of A_ // A_A_B if(is_repeated(start, start + sublen, sublen)) // A_B plus anything formed by that ret += 1 + sources(start + sublen, sublen + 1); // BA_A_ if(is_repeated(start + 1, start + 1 + sublen, sublen)) // BA_ and A_B should be equivalent ret += 1 + sources(start, sublen + 1); // A_BA_ (x2) if(is_repeated(start, start + 1 + sublen, sublen)) // 2 * (A_B + anything formed by that) ret += (1 + sources(start, sublen + 1)) << 1; return ret; } int main() { ofstream fout ("scode.out"); ifstream fin ("scode.in"); // Read input static char str[100+1]; fin >> str; // Calculate output int ret = sources(str, strlen(str)); fout << ret << endl; return 0; }
No comments:
Post a Comment