ADDED SRM/638-U/1A-U.cpp Index: SRM/638-U/1A-U.cpp ================================================================== --- SRM/638-U/1A-U.cpp +++ SRM/638-U/1A-U.cpp @@ -0,0 +1,199 @@ +#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; + +struct UnionFind +{ + vector uf, sz; + int nc; + + UnionFind(int N): uf(N), sz(N,1), nc(N) + { for(int i=0; i= sz[b] ) swap(a, b); + uf[a] = b; + sz[b] += sz[a]; + --nc; + } + return (a!=b); + } +}; + +class ShadowSculpture { public: + string possible(vector XY, vector YZ, vector ZX) + { + const int N = XY.size(); + + // Init + bool XYZ[10][10][10]; + for(int x=0; x id = [&](int x, int y, int z) { + return (x*N+y)*N+z; + }; + + const int dx[] = {-1,+1,0,0,0,0}; + const int dy[] = {0,0,-1,+1,0,0}; + const int dz[] = {0,0,0,0,-1,+1}; + int cnt = 0; + for(int x=0; x +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(_, ShadowSculpture().possible(XY, YZ, ZX));} +int main(){ + +CASE(0) + string XY_[] = {"YN","NN"}; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = {"YN","NN"}; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = {"YN","NN"}; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = "Possible"; +END +CASE(1) + string XY_[] = {"YN","NY"}; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = {"YN","NY"}; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = {"YN","NY"}; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = "Impossible"; +END +CASE(2) + string XY_[] = {"YYY","YNY","YYY"}; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = {"YYY","YNY","YYY"}; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = {"YYY","YNY","YYY"}; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = "Possible"; +END +CASE(3) + string XY_[] = {"YYY","YNY","YYY"}; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = {"NYY","YNY","YYY"}; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = {"YYY","YNY","YYN"}; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = "Impossible"; +END +CASE(4) + string XY_[] = {"N"}; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = {"N"}; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = {"N"}; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = "Possible"; +END +/* +CASE(5) + string XY_[] = ; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = ; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = ; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = ; +END +CASE(6) + string XY_[] = ; + vector XY(XY_, XY_+sizeof(XY_)/sizeof(*XY_)); + string YZ_[] = ; + vector YZ(YZ_, YZ_+sizeof(YZ_)/sizeof(*YZ_)); + string ZX_[] = ; + vector ZX(ZX_, ZX_+sizeof(ZX_)/sizeof(*ZX_)); + string _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/638-U/1B.cpp Index: SRM/638-U/1B.cpp ================================================================== --- SRM/638-U/1B.cpp +++ SRM/638-U/1B.cpp @@ -0,0 +1,111 @@ +#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; + +const int MODVAL = 1000000007; + +class NarrowPassage2 { public: + int count(vector size, int maxSizeSum) + { + if(size.size() <= 1) + return 1; + + int mi = min_element(size.begin(), size.end()) - size.begin(); + + int lm=mi; + for(int k=mi-1; k>=0 && size[k]+size[mi]<=maxSizeSum; --k) + lm = k; + int rm=mi; + for(int k=mi+1; k +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 int& Expected, const int& 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(_, NarrowPassage2().count(size, maxSizeSum));} +int main(){ + +CASE(0) + int size_[] = {1, 2, 3}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 3; + int _ = 2; +END +CASE(1) + int size_[] = {1, 2, 3}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 1000; + int _ = 6; +END +CASE(2) + int size_[] = {1, 2, 3}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 4; + int _ = 3; +END +CASE(3) + int size_[] = {1,1,1,1,1,1,1,1,1,1,1,1,1}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 2; + int _ = 227020758; +END +CASE(4) + int size_[] = {2,4,6,1,3,5}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 8; + int _ = 60; +END +CASE(5) + int size_[] = {1000000000}; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = 1000000000; + int _ = 1; +END +/* +CASE(6) + int size_[] = ; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = ; + int _ = ; +END +CASE(7) + int size_[] = ; + vector size(size_, size_+sizeof(size_)/sizeof(*size_)); + int maxSizeSum = ; + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/638-U/1C-U.cpp Index: SRM/638-U/1C-U.cpp ================================================================== --- SRM/638-U/1C-U.cpp +++ SRM/638-U/1C-U.cpp @@ -0,0 +1,278 @@ +#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; + +const int INF = 0x1fffffff; + +class CandleTimer { public: + int differentTime(vector A, vector B, vector len) + { + if(A.size() == 1) { + // Special case, just in case. All nodes are leaves. + // Either light only one end or both ends. + return 2; + } + + // x2, to make all the possible final points on integer coordinates. + for(auto& li: len) + li *= 2; + + // Prepare.... + const int E = A.size(), V = E+1; + + vector leaf; + vector is_leaf(V, false); + { + vector degree(V); + for(auto a: A) degree[a]++; + for(auto b: B) degree[b]++; + + for(int v=0; v> dist(V, vector(V, INF)); + { + for(int i=0; i>> G(V); // len, dest + for(int e=0; e> cand; + { + vector done(V, false); + + // Add all leaves as the possible final point + for(int e=0; e c(e, (ll+dist[lb][b]-dist[la][a])/2); + // TODO: reduce by done[] + cand.push_back(c); + } + } else if(dist[la][b]+ll+dist[lb][a] == dist[la][lb]) { + if(abs(dist[la][b] - dist[lb][a]) <= ll) { + tuple c(e, (ll+dist[la][b]-dist[lb][a])/2); + // TODO: reduce by done[] + cand.push_back(c); + } + } + } + } + + // Distance between a candidate point and a node. + function,int)> calc_d = [&](tuple c, int v) { + return min( + dist[A[get(c)]][v] + get(c), + dist[B[get(c)]][v] + len[get(c)] - get(c) + ); + }; + + // Simulate all. + set answer; + for(auto c: cand) + { + vector> dist_leaf; + for(int v: leaf) + dist_leaf.emplace_back(calc_d(c, v), v); + sort(dist_leaf.begin(), dist_leaf.end()); + + for(int i=0; i0 && cand_time == dist_leaf[i-1].first) + continue; + + // Light all leaves further or equal to dist_leaf[i]. + // Can the point |c| be the last point (burning at |cand_time|?) + + // Dijkstra. + vector burn_time(V, INF); + { + priority_queue, vector>, greater>> Q; + for(int k=i; k= cand_time) + answer.insert(cand_time); + } + } + + return answer.size(); + } +}; + +// 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 int& Expected, const int& 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(_, CandleTimer().differentTime(A, B, len));} +int main(){ + +CASE(0) + int A_[] = {0,1}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1,2}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {10,1}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 2; +END +CASE(1) + int A_[] = {0,0,0}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1,2,3}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {1,1,1}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 2; +END +CASE(2) + int A_[] = {0,0,0}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1,2,3}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {1,2,3}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 4; +END +CASE(3) + int A_[] = {0,1,1,2,3,3,2,4}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1,2,3,4,5,6,7,8}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {5,3,2,4,6,8,7,1}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 7; +END +CASE(4) + int A_[] = {0,0,0,0}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1,2,3,4}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {123,456,789,1000}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 8; +END +CASE(5) + int A_[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {0,1,2,0,0,0,1,0,0,0,2,5,4,7,13,13,6,15,11,18,19,21,22,16,19,19,20,18,22,27}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {59,58,147,169,34,14,150,55,156,151,130,109,124,15,100,1,156,16,38,97,99,132,150,18,27,91,110,127,15,105}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 65; +END +CASE(6) + int A_[] = {0}; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = {1}; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = {1000}; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = 2; +END +/* +CASE(7) + int A_[] = ; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = ; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = ; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = ; +END +CASE(8) + int A_[] = ; + vector A(A_, A_+sizeof(A_)/sizeof(*A_)); + int B_[] = ; + vector B(B_, B_+sizeof(B_)/sizeof(*B_)); + int len_[] = ; + vector len(len_, len_+sizeof(len_)/sizeof(*len_)); + int _ = ; +END +*/ +} +// END CUT HERE