98c5c562ca 2015-02-02 kinaba: #include <iostream> 98c5c562ca 2015-02-02 kinaba: #include <sstream> 98c5c562ca 2015-02-02 kinaba: #include <iomanip> 98c5c562ca 2015-02-02 kinaba: #include <vector> 98c5c562ca 2015-02-02 kinaba: #include <string> 98c5c562ca 2015-02-02 kinaba: #include <map> 98c5c562ca 2015-02-02 kinaba: #include <set> 98c5c562ca 2015-02-02 kinaba: #include <algorithm> 98c5c562ca 2015-02-02 kinaba: #include <numeric> 98c5c562ca 2015-02-02 kinaba: #include <iterator> 98c5c562ca 2015-02-02 kinaba: #include <functional> 98c5c562ca 2015-02-02 kinaba: #include <complex> 98c5c562ca 2015-02-02 kinaba: #include <queue> 98c5c562ca 2015-02-02 kinaba: #include <stack> 98c5c562ca 2015-02-02 kinaba: #include <cmath> 98c5c562ca 2015-02-02 kinaba: #include <cassert> 98c5c562ca 2015-02-02 kinaba: #include <tuple> 98c5c562ca 2015-02-02 kinaba: using namespace std; 98c5c562ca 2015-02-02 kinaba: typedef long long LL; 98c5c562ca 2015-02-02 kinaba: typedef complex<double> CMP; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: class TheGridDivOne { public: 98c5c562ca 2015-02-02 kinaba: int find(vector <int> x, vector <int> y, int k) 98c5c562ca 2015-02-02 kinaba: { 98c5c562ca 2015-02-02 kinaba: enum {X, Y}; 98c5c562ca 2015-02-02 kinaba: typedef tuple<int,int> Point; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: set<Point> blocked; 98c5c562ca 2015-02-02 kinaba: map<int, set<int>> x2y; 98c5c562ca 2015-02-02 kinaba: x2y[0].emplace(0); 98c5c562ca 2015-02-02 kinaba: for(int i=0; i<x.size(); ++i) { 98c5c562ca 2015-02-02 kinaba: blocked.emplace(x[i], y[i]); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]-1].emplace(y[i]-1); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]-1].emplace(y[i]+0); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]-1].emplace(y[i]+1); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]+0].emplace(y[i]-1); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]+0].emplace(y[i]+1); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]+1].emplace(y[i]-1); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]+1].emplace(y[i]+0); 98c5c562ca 2015-02-02 kinaba: x2y[x[i]+1].emplace(y[i]+1); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: map<int, set<int>> x2y_aug = x2y; 98c5c562ca 2015-02-02 kinaba: for(auto it=x2y.begin(); it!=x2y.end(); ++it) { 98c5c562ca 2015-02-02 kinaba: auto kt = it; ++kt; 98c5c562ca 2015-02-02 kinaba: if(kt != x2y.end()) { 98c5c562ca 2015-02-02 kinaba: for(int y: it->second) 98c5c562ca 2015-02-02 kinaba: x2y_aug[kt->first].emplace(y); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: if(it != x2y.begin()) { 98c5c562ca 2015-02-02 kinaba: auto kt = it; --kt; 98c5c562ca 2015-02-02 kinaba: for(int y: it->second) 98c5c562ca 2015-02-02 kinaba: x2y_aug[kt->first].emplace(y); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: vector<Point> pts; 98c5c562ca 2015-02-02 kinaba: for(auto& xys: x2y_aug) { 98c5c562ca 2015-02-02 kinaba: int x = xys.first; 98c5c562ca 2015-02-02 kinaba: for(int y: xys.second) { 98c5c562ca 2015-02-02 kinaba: Point q(x,y); 98c5c562ca 2015-02-02 kinaba: if(!blocked.count(q)) 98c5c562ca 2015-02-02 kinaba: pts.emplace_back(q); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: typedef int Vert; 98c5c562ca 2015-02-02 kinaba: const int N = pts.size(); 98c5c562ca 2015-02-02 kinaba: const int S = std::find(pts.begin(), pts.end(), Point(0,0)) - pts.begin(); 98c5c562ca 2015-02-02 kinaba: typedef int Cost; 98c5c562ca 2015-02-02 kinaba: typedef pair<Cost,Vert> Edge; 98c5c562ca 2015-02-02 kinaba: typedef vector<Edge> Edges; 98c5c562ca 2015-02-02 kinaba: typedef vector<Edges> Graph; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: Graph G(N); 98c5c562ca 2015-02-02 kinaba: for(int i=0; i<N; ++i) 98c5c562ca 2015-02-02 kinaba: for(int k=i+1; k<N; ++k) { 98c5c562ca 2015-02-02 kinaba: bool connected = true; 98c5c562ca 2015-02-02 kinaba: int x1 = get<X>(pts[i]); 98c5c562ca 2015-02-02 kinaba: int x2 = get<X>(pts[k]); 98c5c562ca 2015-02-02 kinaba: int y1 = get<Y>(pts[i]); 98c5c562ca 2015-02-02 kinaba: int y2 = get<Y>(pts[k]); 98c5c562ca 2015-02-02 kinaba: for(Point b: blocked) { 98c5c562ca 2015-02-02 kinaba: if(min(y1,y2)<=get<Y>(b) && get<Y>(b)<=max(y1,y2) && 98c5c562ca 2015-02-02 kinaba: min(x1,x2)<=get<X>(b) && get<X>(b)<=max(x1,x2)) { 98c5c562ca 2015-02-02 kinaba: connected = false; 98c5c562ca 2015-02-02 kinaba: break; 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: // If not blocked then add i<-->k with Manhattan cost 98c5c562ca 2015-02-02 kinaba: if(connected) { 98c5c562ca 2015-02-02 kinaba: G[i].emplace_back(abs(x1-x2)+abs(y1-y2), k); 98c5c562ca 2015-02-02 kinaba: G[k].emplace_back(abs(x1-x2)+abs(y1-y2), i); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: // Dijkstra 98c5c562ca 2015-02-02 kinaba: priority_queue<Edge, vector<Edge>, greater<Edge>> Q; 98c5c562ca 2015-02-02 kinaba: Q.emplace(0, S); 98c5c562ca 2015-02-02 kinaba: vector<Cost> D(N, -1); 98c5c562ca 2015-02-02 kinaba: while(!Q.empty()) { 98c5c562ca 2015-02-02 kinaba: Cost c = Q.top().first; 98c5c562ca 2015-02-02 kinaba: Vert v = Q.top().second; 98c5c562ca 2015-02-02 kinaba: Q.pop(); 98c5c562ca 2015-02-02 kinaba: if(D[v]!=-1) 98c5c562ca 2015-02-02 kinaba: continue; 98c5c562ca 2015-02-02 kinaba: D[v] = c; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: for(auto e: G[v]) { 98c5c562ca 2015-02-02 kinaba: Cost c2 = c + e.first; 98c5c562ca 2015-02-02 kinaba: Vert q = e.second; 98c5c562ca 2015-02-02 kinaba: if(D[q]==-1) 98c5c562ca 2015-02-02 kinaba: Q.emplace(c2, q); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: int best = 0; 98c5c562ca 2015-02-02 kinaba: for(Vert v=0; v<N; ++v) { 98c5c562ca 2015-02-02 kinaba: if(D[v] != -1 && D[v]<=k) { 98c5c562ca 2015-02-02 kinaba: // the point 98c5c562ca 2015-02-02 kinaba: best = max(best, get<X>(pts[v])); 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: // if not blocked... 98c5c562ca 2015-02-02 kinaba: Point right(get<X>(pts[v])+1, get<Y>(pts[v])); 98c5c562ca 2015-02-02 kinaba: if(blocked.count(right)) 98c5c562ca 2015-02-02 kinaba: continue; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: // go more east 98c5c562ca 2015-02-02 kinaba: bool skip = false; 98c5c562ca 2015-02-02 kinaba: for(Edge e: G[v]) { 98c5c562ca 2015-02-02 kinaba: Vert u = e.second; 98c5c562ca 2015-02-02 kinaba: if(get<Y>(pts[u]) == get<Y>(pts[v]) && get<X>(pts[u]) > get<X>(pts[v]) 98c5c562ca 2015-02-02 kinaba: && D[u]!=-1 && D[u]<=k) { 98c5c562ca 2015-02-02 kinaba: skip = true; 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: if(!skip) { 98c5c562ca 2015-02-02 kinaba: int sec = k-D[v]; 98c5c562ca 2015-02-02 kinaba: best = max(best, get<X>(pts[v]) + sec); 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: return best; 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: }; 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: // BEGIN CUT HERE 98c5c562ca 2015-02-02 kinaba: #include <ctime> 98c5c562ca 2015-02-02 kinaba: double start_time; string timer() 98c5c562ca 2015-02-02 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 98c5c562ca 2015-02-02 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 98c5c562ca 2015-02-02 kinaba: { os << "{ "; 98c5c562ca 2015-02-02 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 98c5c562ca 2015-02-02 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 98c5c562ca 2015-02-02 kinaba: void verify_case(const int& Expected, const int& Received) { 98c5c562ca 2015-02-02 kinaba: bool ok = (Expected == Received); 98c5c562ca 2015-02-02 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 98c5c562ca 2015-02-02 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 98c5c562ca 2015-02-02 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 98c5c562ca 2015-02-02 kinaba: #define END verify_case(_, TheGridDivOne().find(x, y, k));} 98c5c562ca 2015-02-02 kinaba: int main(){ 98c5c562ca 2015-02-02 kinaba: 98c5c562ca 2015-02-02 kinaba: CASE(0) 98c5c562ca 2015-02-02 kinaba: int x_[] = {1,1,1,1}; 98c5c562ca 2015-02-02 kinaba: vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 98c5c562ca 2015-02-02 kinaba: int y_[] = {-2,-1,0,1}; 98c5c562ca 2015-02-02 kinaba: vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 98c5c562ca 2015-02-02 kinaba: int k = 4; 98c5c562ca 2015-02-02 kinaba: int _ = 2; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: CASE(1) 98c5c562ca 2015-02-02 kinaba: int x_[] = {-1, 0, 0, 1}; 98c5c562ca 2015-02-02 kinaba: vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 98c5c562ca 2015-02-02 kinaba: int y_[] = {0, -1, 1, 0}; 98c5c562ca 2015-02-02 kinaba: vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 98c5c562ca 2015-02-02 kinaba: int k = 9; 98c5c562ca 2015-02-02 kinaba: int _ = 0; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: CASE(2) 98c5c562ca 2015-02-02 kinaba: vector <int> x; 98c5c562ca 2015-02-02 kinaba: vector <int> y; 98c5c562ca 2015-02-02 kinaba: int k = 1000; 98c5c562ca 2015-02-02 kinaba: int _ = 1000; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: CASE(3) 98c5c562ca 2015-02-02 kinaba: int x_[] = {1,0,0,-1,-1,-2,-2,-3,-3,-4,-4}; 98c5c562ca 2015-02-02 kinaba: vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 98c5c562ca 2015-02-02 kinaba: int y_[] = {0,-1,1,-2,2,-3,3,-4,4,-5,5}; 98c5c562ca 2015-02-02 kinaba: vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 98c5c562ca 2015-02-02 kinaba: int k = 47; 98c5c562ca 2015-02-02 kinaba: int _ = 31; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: /* 98c5c562ca 2015-02-02 kinaba: CASE(4) 98c5c562ca 2015-02-02 kinaba: int x_[] = ; 98c5c562ca 2015-02-02 kinaba: vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 98c5c562ca 2015-02-02 kinaba: int y_[] = ; 98c5c562ca 2015-02-02 kinaba: vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 98c5c562ca 2015-02-02 kinaba: int k = ; 98c5c562ca 2015-02-02 kinaba: int _ = ; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: CASE(5) 98c5c562ca 2015-02-02 kinaba: int x_[] = ; 98c5c562ca 2015-02-02 kinaba: vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 98c5c562ca 2015-02-02 kinaba: int y_[] = ; 98c5c562ca 2015-02-02 kinaba: vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 98c5c562ca 2015-02-02 kinaba: int k = ; 98c5c562ca 2015-02-02 kinaba: int _ = ; 98c5c562ca 2015-02-02 kinaba: END 98c5c562ca 2015-02-02 kinaba: */ 98c5c562ca 2015-02-02 kinaba: } 98c5c562ca 2015-02-02 kinaba: // END CUT HERE