ADDED SRM/645-U/1A.cpp Index: SRM/645-U/1A.cpp ================================================================== --- SRM/645-U/1A.cpp +++ SRM/645-U/1A.cpp @@ -0,0 +1,102 @@ +#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; + +class TheConsecutiveIntegersDivOne { public: + int find(vector numbers, int k) + { + sort(numbers.begin(), numbers.end()); + int best = 0x7fffffff; + for(int fixed=0; fixed +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(_, TheConsecutiveIntegersDivOne().find(numbers, k));} +int main(){ + +CASE(0) + int numbers_[] = {4, 7, 47}; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = 2; + int _ = 2; +END +CASE(1) + int numbers_[] = {1, 100}; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = 1; + int _ = 0; +END +CASE(2) + int numbers_[] = {-96, -53, 82, -24, 6, -75}; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = 2; + int _ = 20; +END +CASE(3) + int numbers_[] = {64, -31, -56}; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = 2; + int _ = 24; +END +CASE(4) + int numbers_[] = {-96, -53, 82, -24, 6, -75}; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = 4; + int _ = 90; +END +/* +CASE(5) + int numbers_[] = ; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = ; + int _ = ; +END +CASE(6) + int numbers_[] = ; + vector numbers(numbers_, numbers_+sizeof(numbers_)/sizeof(*numbers_)); + int k = ; + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/645-U/2B-U.cpp Index: SRM/645-U/2B-U.cpp ================================================================== --- SRM/645-U/2B-U.cpp +++ SRM/645-U/2B-U.cpp @@ -0,0 +1,214 @@ +#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; + +class TheGridDivOne { public: + int find(vector x, vector y, int k) + { + enum {X, Y}; + typedef tuple Point; + + set blocked; + map> x2y; + x2y[0].emplace(0); + for(int i=0; i> x2y_aug = x2y; + for(auto it=x2y.begin(); it!=x2y.end(); ++it) { + auto kt = it; ++kt; + if(kt != x2y.end()) { + for(int y: it->second) + x2y_aug[kt->first].emplace(y); + } + if(it != x2y.begin()) { + auto kt = it; --kt; + for(int y: it->second) + x2y_aug[kt->first].emplace(y); + } + } + + vector pts; + for(auto& xys: x2y_aug) { + int x = xys.first; + for(int y: xys.second) { + Point q(x,y); + if(!blocked.count(q)) + pts.emplace_back(q); + } + } + + typedef int Vert; + const int N = pts.size(); + const int S = std::find(pts.begin(), pts.end(), Point(0,0)) - pts.begin(); + typedef int Cost; + typedef pair Edge; + typedef vector Edges; + typedef vector Graph; + + Graph G(N); + for(int i=0; i(pts[i]); + int x2 = get(pts[k]); + int y1 = get(pts[i]); + int y2 = get(pts[k]); + for(Point b: blocked) { + if(min(y1,y2)<=get(b) && get(b)<=max(y1,y2) && + min(x1,x2)<=get(b) && get(b)<=max(x1,x2)) { + connected = false; + break; + } + } + // If not blocked then add i<-->k with Manhattan cost + if(connected) { + G[i].emplace_back(abs(x1-x2)+abs(y1-y2), k); + G[k].emplace_back(abs(x1-x2)+abs(y1-y2), i); + } + } + + // Dijkstra + priority_queue, greater> Q; + Q.emplace(0, S); + vector D(N, -1); + while(!Q.empty()) { + Cost c = Q.top().first; + Vert v = Q.top().second; + Q.pop(); + if(D[v]!=-1) + continue; + D[v] = c; + + for(auto e: G[v]) { + Cost c2 = c + e.first; + Vert q = e.second; + if(D[q]==-1) + Q.emplace(c2, q); + } + } + + int best = 0; + for(Vert v=0; v(pts[v])); + + + // if not blocked... + Point right(get(pts[v])+1, get(pts[v])); + if(blocked.count(right)) + continue; + + // go more east + bool skip = false; + for(Edge e: G[v]) { + Vert u = e.second; + if(get(pts[u]) == get(pts[v]) && get(pts[u]) > get(pts[v]) + && D[u]!=-1 && D[u]<=k) { + skip = true; + } + } + if(!skip) { + int sec = k-D[v]; + best = max(best, get(pts[v]) + sec); + } + } + } + + return best; + } +}; + +// 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(_, TheGridDivOne().find(x, y, k));} +int main(){ + +CASE(0) + int x_[] = {1,1,1,1}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {-2,-1,0,1}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + int k = 4; + int _ = 2; +END +CASE(1) + int x_[] = {-1, 0, 0, 1}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {0, -1, 1, 0}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + int k = 9; + int _ = 0; +END +CASE(2) + vector x; + vector y; + int k = 1000; + int _ = 1000; +END +CASE(3) + int x_[] = {1,0,0,-1,-1,-2,-2,-3,-3,-4,-4}; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = {0,-1,1,-2,2,-3,3,-4,4,-5,5}; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + int k = 47; + int _ = 31; +END +/* +CASE(4) + int x_[] = ; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = ; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + int k = ; + int _ = ; +END +CASE(5) + int x_[] = ; + vector x(x_, x_+sizeof(x_)/sizeof(*x_)); + int y_[] = ; + vector y(y_, y_+sizeof(y_)/sizeof(*y_)); + int k = ; + int _ = ; +END +*/ +} +// END CUT HERE