Skip to content

Instantly share code, notes, and snippets.

@kusano
Created May 12, 2016 16:54
Show Gist options
  • Save kusano/1866478af8199a977c159552f51cc6aa to your computer and use it in GitHub Desktop.
Save kusano/1866478af8199a977c159552f51cc6aa to your computer and use it in GitHub Desktop.
#include <vector>
#include <map>
#include <functional>
#include <algorithm>
using namespace std;
// BEGIN CUT HERE
#include <iostream>
#include <sstream>
#include <string>
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v);
// END CUT HERE
class LCMGCD{public:
string isPossible( vector <int> x, int t )
{
int n = (int)x.size();
vector<int> a(n), b(n);
for (int i=0; i<n; i++)
{
while (x[i]%2==0)
x[i] /= 2,
a[i]++;
while (x[i]%3==0)
x[i] /= 3,
b[i]++;
}
int ta=0, tb=0;
while (t%2==0)
t/=2,
ta++;
while (t%3==0)
t/=3,
tb++;
for (int i=0; i<n; i++)
{
a[i] = a[i]>ta ? 1 : a[i]<ta ? -1 : 0;
b[i] = b[i]>tb ? 1 : b[i]<tb ? -1 : 0;
}
map<pair<int,int>, int> M;
vector<pair<int,int>> A;
for (int i=0; i<n; i++)
{
pair<int,int> p = make_pair(a[i], b[i]);
//if (M[p]>=2)
if (M[p]>=1)
continue;
M[p]++;
A.push_back(p);
}
n = (int)A.size();
vector<int> memo(1<<n, -1);
auto ab2p = [](int a, int b){return (a+1)*3 + (b+1);};
function<int(int)> BT = [&](int s)->int
{
if (memo[s]!=-1)
return memo[s];
int c = 0;
int a, b;
for (int i=0; i<n; i++)
if (s>>i&1)
c++,
a = A[i].first,
b = A[i].second;
if (c==1)
{
return memo[s] = 1<<ab2p(a, b);
}
int ret = 0;
for (int s1=s; s1>0; s1=(s1-1)&s)
{
int s2 = s^s1;
if (s2>0)
{
int r1 = BT(s1);
int r2 = BT(s2);
for (int c1=0; c1<9; c1++)
if (r1>>c1&1)
for (int c2=0; c2<9; c2++)
if (r2>>c2&1)
{
int a1 = c1/3-1;
int b1 = c1%3-1;
int a2 = c2/3-1;
int b2 = c2%3-1;
ret |= 1<<ab2p(max(a1,a2), max(b1,b2));
ret |= 1<<ab2p(min(a1,a2), min(b1,b2));
}
}
}
return memo[s] = ret;
};
return BT((1<<n)-1)>>ab2p(0,0)&1 ? "Possible" : "Impossible";
}};
// BEGIN CUT HERE
#include <ctime>
double start_time; string timer()
{ ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
{ os << "{ ";
for(typename vector<T>::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(_, LCMGCD().isPossible(x, t));}
int main(){
CASE(0)
int x_[] = {2,3};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 6;
string _ = "Possible";
END
CASE(1)
int x_[] = {4,9};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 6;
string _ = "Impossible";
END
CASE(2)
int x_[] = {6,12,24,18,36,72,54,108,216};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 36;
string _ = "Possible";
END
CASE(3)
int x_[] = {6,27,81,729};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 6;
string _ = "Impossible";
END
CASE(4)
int x_[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 1;
string _ = "Possible";
END
CASE(5)
int x_[] = {72,16,16,16,16,16,27,27,27,27,27,27,27,27,27};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 72;
string _ = "Possible";
END
CASE(6)
int x_[] = {100663296, 544195584, 229582512, 59049};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 60466176;
string _ = "Possible";
END
CASE(7)
int x_[] = {2,4,8,16,32,64};
vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_));
int t = 256;
string _ = "Impossible";
END
}
// END CUT HERE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment