ADDED SRM/TCO17-3A-U/1A.cpp Index: SRM/TCO17-3A-U/1A.cpp ================================================================== --- SRM/TCO17-3A-U/1A.cpp +++ SRM/TCO17-3A-U/1A.cpp @@ -0,0 +1,205 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef complex CMP; + +int gcd(int a, int b) +{ + while (a) + swap(a, b %= a); + return b; +} + +bool is_coprime(int a, int b) +{ + return gcd(a, b) == 1; +} + +class CoprimeMatrix { public: + vector is_p; + vector primes; + + string isPossible(vector coprime) + { + // eratos + if (is_p.empty()) { + is_p.assign(60, true); + is_p[0] = is_p[1] = false; + for (int p = 2; p < is_p.size(); ++p) if (is_p[p]) { + primes.push_back(p); + for (int q = p + p; q < is_p.size(); q += p) + is_p[q] = false; + } + } + + return solve(coprime) ? "Possible" : "Impossible"; + } + + bool solve(const vector& coprime) + { + const int N = coprime.size(); + + // sanity + for (int i = 0; i < N; ++i) + for (int k = 0; k < N; ++k) + if (coprime[i][k] != coprime[k][i]) + return false; + + // trivial case + for (int i = 0; i < N; ++i) + for (int k = 0; k < N; ++k) + if (is_coprime(1 + i, 1 + k) != (coprime[i][k] == 'Y')) + goto nontrivial; + return true; + + nontrivial: + for (int i = 0; i < N; ++i) + if(coprime[i][i]=='Y') + return false; + + vector> cos; + for (int off = 0; off < N; ++off) { + vector co; + for (int t = 0; t + off < N; ++t) + co.push_back(coprime[off][off + t] == 'Y'); + + // x+off coprime with k in 0,1,2,,,,co.size()-1 iff co[k] + + if (!can(co)) + return false; + cos.push_back(co); + } + + for (int p = 2; p < N; ++p) if (is_p[p]) { + int last = -1; + for(int o=0; op; ++o) + if (cos[o][p] == false) { + if (last!=-1 && (o-last)!=p) + return false; + last = o; + } + else { + if (o - last >= p) + return false; + } + } + + return true; + } + + bool can(const vector& co) + { + // Can there be a positive n such that coprime(n,i) == co[i] ? + vector prime_factors; + for (int p = 2; p < co.size(); ++p) + if (is_p[p] && !co[p]) + prime_factors.push_back(p); + + for (int k = 0; k < co.size(); ++k) + if (is_coprimev(k, prime_factors) != co[k]) { + prime_factors.push_back(primes.back()); + for (int k = 0; k < co.size(); ++k) + if (is_coprimev(k, prime_factors) != co[k]) + return false; + return true; + } + return true; + } + + bool is_coprimev(int k, const vector& pfs) + { + for (int p : pfs) + if (k%p == 0) + return false; + return true; + } +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const string& Expected, const string& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, CoprimeMatrix().isPossible(coprime));} +int main(){ + +CASE(0) + string coprime_[] = {"NYNYN", + "YNYYN", + "NYNYN", + "YYYNY", + "NNNYN"}; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Possible"; +END +CASE(1) + string coprime_[] = {"NY", + "NN"}; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Impossible"; +END +CASE(2) + string coprime_[] = {"NYYYYN", + "YNYNNN", + "YYNYYY", + "YNYNYN", + "YNYYNY", + "NNYNYN"}; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Possible"; +END +CASE(3) + string coprime_[] = {"NN", + "NN"}; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Impossible"; +END +CASE(4) +// both x and x+1 and x+2 are coprime with 2 + string coprime_[] = +{ + "NYYY", + "YNYY", + "YYNY", + "YYYN", +}; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Impossible"; +END +CASE(5) +// x+1 == 1 +string coprime_[] = { "NY", "YY" }; + vector coprime(coprime_, coprime_+sizeof(coprime_)/sizeof(*coprime_)); + string _ = "Impossible"; +END +CASE(6) +string coprime_[] = { "Y" }; +vector coprime(coprime_, coprime_ + sizeof(coprime_) / sizeof(*coprime_)); +string _ = "Possible"; +END +} +// END CUT HERE