4fd800b3a8 2011-02-23 kinaba: #include <iostream> 4fd800b3a8 2011-02-23 kinaba: #include <sstream> 4fd800b3a8 2011-02-23 kinaba: #include <iomanip> 4fd800b3a8 2011-02-23 kinaba: #include <vector> 4fd800b3a8 2011-02-23 kinaba: #include <string> 4fd800b3a8 2011-02-23 kinaba: #include <map> 4fd800b3a8 2011-02-23 kinaba: #include <set> 4fd800b3a8 2011-02-23 kinaba: #include <algorithm> 4fd800b3a8 2011-02-23 kinaba: #include <numeric> 4fd800b3a8 2011-02-23 kinaba: #include <iterator> 4fd800b3a8 2011-02-23 kinaba: #include <functional> 4fd800b3a8 2011-02-23 kinaba: #include <complex> 4fd800b3a8 2011-02-23 kinaba: #include <queue> 4fd800b3a8 2011-02-23 kinaba: #include <stack> 4fd800b3a8 2011-02-23 kinaba: #include <cmath> 4fd800b3a8 2011-02-23 kinaba: #include <cassert> 4fd800b3a8 2011-02-23 kinaba: #include <cstring> 4fd800b3a8 2011-02-23 kinaba: using namespace std; 4fd800b3a8 2011-02-23 kinaba: typedef long long LL; 4fd800b3a8 2011-02-23 kinaba: typedef complex<double> CMP; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: class InfiniteLab { public: 4fd800b3a8 2011-02-23 kinaba: long long getDistance(vector <string> map, long long r1, int c1, long long r2, int c2) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: LL H = map.size(); 4fd800b3a8 2011-02-23 kinaba: LL W = map[0].size(); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: if( r1 > r2 ) { 4fd800b3a8 2011-02-23 kinaba: swap(r1,r2); 4fd800b3a8 2011-02-23 kinaba: swap(c1,c2); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: if( r1 < 0 ) { 4fd800b3a8 2011-02-23 kinaba: // check!!!! 4fd800b3a8 2011-02-23 kinaba: LL Hx = (-r1/H + 1)*H; 4fd800b3a8 2011-02-23 kinaba: r1 += Hx; 4fd800b3a8 2011-02-23 kinaba: r2 += Hx; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: cerr << r1 << " " << r2 << endl; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: vector<string> mmm(map); 4fd800b3a8 2011-02-23 kinaba: mmm.insert(mmm.end(), map.begin(), map.end()); 4fd800b3a8 2011-02-23 kinaba: mmm.insert(mmm.end(), map.begin(), map.end()); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: if( r1/H == r2/H ) 4fd800b3a8 2011-02-23 kinaba: return dist(mmm, H+(r1%H), c1, H+(r2%H), c2); 4fd800b3a8 2011-02-23 kinaba: return -1; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // top to top 4fd800b3a8 2011-02-23 kinaba: vector<vector<LL> > tochu(W, vector<LL>(W, -1)); 4fd800b3a8 2011-02-23 kinaba: for(int x1=0; x1<W; ++x1) if( map[0][x1] != '#' ) 4fd800b3a8 2011-02-23 kinaba: for(int x2=0; x2<W; ++x2) if( map[0][x2] != '#' ) 4fd800b3a8 2011-02-23 kinaba: tochu[x1][x2] = dist( mmm, H, x1, H*2, x2 ); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // r1c1 to top 4fd800b3a8 2011-02-23 kinaba: vector<LL> from(W, -1); 4fd800b3a8 2011-02-23 kinaba: for(int x1=0; x1<W; ++x1) if( map[0][x1] != '#' ) 4fd800b3a8 2011-02-23 kinaba: from[W] = dist( mmm, H+(r1%H), c1, H*2, x1 ); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // top to r2c2 4fd800b3a8 2011-02-23 kinaba: vector<LL> to(W, -1); 4fd800b3a8 2011-02-23 kinaba: for(int x1=0; x1<W; ++x1) if( map[0][x1] != '#' ) 4fd800b3a8 2011-02-23 kinaba: to[W] = dist( mmm, H, x1, H*2+(r2%H), c2 ); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: LL best = -1; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<from.size(); ++i) if( from[i]>=0 ) 4fd800b3a8 2011-02-23 kinaba: for(int j=0; j<to.size(); ++j) if( to[j]>=0 ) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: LL sc = from[i] + to[j]; 4fd800b3a8 2011-02-23 kinaba: LL s2 = -1; // TODO! 4fd800b3a8 2011-02-23 kinaba: if( s2 != -1 && (best == -1 || s2+sc<best) ) 4fd800b3a8 2011-02-23 kinaba: best = s2+sc; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return best; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: LL dist(vector<string>& mmm, LL y1, LL x1, LL y2, LL x2) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: vector< pair<LL,LL> > Q; 4fd800b3a8 2011-02-23 kinaba: set< pair<LL,LL> > V; 4fd800b3a8 2011-02-23 kinaba: Q.push_back( make_pair(y1,x1) ); 4fd800b3a8 2011-02-23 kinaba: V.insert( make_pair(y1,x1) ); 4fd800b3a8 2011-02-23 kinaba: for(int d=0; !Q.empty(); ++d) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: vector< pair<LL,LL> > Q_next; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<Q.size(); ++i) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: LL y = Q[i].first; 4fd800b3a8 2011-02-23 kinaba: LL x = Q[i].second; 4fd800b3a8 2011-02-23 kinaba: if( y==y2 && x==x2 ) 4fd800b3a8 2011-02-23 kinaba: return d; 4fd800b3a8 2011-02-23 kinaba: int dy[] = {-1,+1,0,0}; 4fd800b3a8 2011-02-23 kinaba: int dx[] = {0,0,-1,+1}; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<4; ++i) { 4fd800b3a8 2011-02-23 kinaba: LL yy = y+dy[i]; 4fd800b3a8 2011-02-23 kinaba: LL xx = x+dx[i]; 4fd800b3a8 2011-02-23 kinaba: if( 0<=yy && yy<mmm.size() && 0<=xx && xx<mmm[0].size() && mmm[yy][xx]!='#' ) { 4fd800b3a8 2011-02-23 kinaba: pair<LL,LL> p(yy,xx); 4fd800b3a8 2011-02-23 kinaba: if( ! V.count(p) ) { 4fd800b3a8 2011-02-23 kinaba: V.insert(p); 4fd800b3a8 2011-02-23 kinaba: Q_next.push_back(p); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: if( mmm[y][x] == 'T' ) { 4fd800b3a8 2011-02-23 kinaba: for(int xt=0; xt<mmm[y].size(); ++xt) if(xt!=x && mmm[y][xt]=='T') { 4fd800b3a8 2011-02-23 kinaba: pair<LL,LL> p(y,xt); 4fd800b3a8 2011-02-23 kinaba: if( ! V.count(p) ) { 4fd800b3a8 2011-02-23 kinaba: V.insert(p); 4fd800b3a8 2011-02-23 kinaba: Q_next.push_back(p); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: break; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: Q_next.swap(Q); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return -1; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // BEGIN CUT HERE 4fd800b3a8 2011-02-23 kinaba: #include <ctime> 4fd800b3a8 2011-02-23 kinaba: double start_time; string timer() 4fd800b3a8 2011-02-23 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 4fd800b3a8 2011-02-23 kinaba: { os << "{ "; 4fd800b3a8 2011-02-23 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 4fd800b3a8 2011-02-23 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 4fd800b3a8 2011-02-23 kinaba: void verify_case(const long long& Expected, const long long& Received) { 4fd800b3a8 2011-02-23 kinaba: bool ok = (Expected == Received); 4fd800b3a8 2011-02-23 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 4fd800b3a8 2011-02-23 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 4fd800b3a8 2011-02-23 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 4fd800b3a8 2011-02-23 kinaba: #define END verify_case(_, InfiniteLab().getDistance(map, r1, c1, r2, c2));} 4fd800b3a8 2011-02-23 kinaba: int main(){ 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: CASE(0) 4fd800b3a8 2011-02-23 kinaba: string map_[] = {"#...##", 4fd800b3a8 2011-02-23 kinaba: ".##...", 4fd800b3a8 2011-02-23 kinaba: "..#.##", 4fd800b3a8 2011-02-23 kinaba: "#.#.##"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = 1LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = 0; 4fd800b3a8 2011-02-23 kinaba: long long r2 = 5LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = 3; 4fd800b3a8 2011-02-23 kinaba: long long _ = 7LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: CASE(1) 4fd800b3a8 2011-02-23 kinaba: string map_[] = {"##.#.", 4fd800b3a8 2011-02-23 kinaba: ".#T#T", 4fd800b3a8 2011-02-23 kinaba: "...#.", 4fd800b3a8 2011-02-23 kinaba: "##.#."}; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = 7LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = 4; 4fd800b3a8 2011-02-23 kinaba: long long r2 = 1LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = 0; 4fd800b3a8 2011-02-23 kinaba: long long _ = 9LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: CASE(2) 4fd800b3a8 2011-02-23 kinaba: string map_[] = {"..######.#", 4fd800b3a8 2011-02-23 kinaba: ".###T###.T", 4fd800b3a8 2011-02-23 kinaba: "..T#.##T##", 4fd800b3a8 2011-02-23 kinaba: ".######..#"}; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = 1LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = 0; 4fd800b3a8 2011-02-23 kinaba: long long r2 = 6LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = 4; 4fd800b3a8 2011-02-23 kinaba: long long _ = 11LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: CASE(3) 4fd800b3a8 2011-02-23 kinaba: string map_[] = {"..#..", 4fd800b3a8 2011-02-23 kinaba: ".#.#.", 4fd800b3a8 2011-02-23 kinaba: "....."}; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = -29LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = 2; 4fd800b3a8 2011-02-23 kinaba: long long r2 = 19LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = 2; 4fd800b3a8 2011-02-23 kinaba: long long _ = 54LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: CASE(4) 4fd800b3a8 2011-02-23 kinaba: string map_[] = {".#.#.", 4fd800b3a8 2011-02-23 kinaba: "..#..", 4fd800b3a8 2011-02-23 kinaba: ".....", 4fd800b3a8 2011-02-23 kinaba: ".....", 4fd800b3a8 2011-02-23 kinaba: "..#.."}; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = -999LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = 3; 4fd800b3a8 2011-02-23 kinaba: long long r2 = 100LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = 2; 4fd800b3a8 2011-02-23 kinaba: long long _ = -1LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: /* 4fd800b3a8 2011-02-23 kinaba: CASE(5) 4fd800b3a8 2011-02-23 kinaba: string map_[] = ; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = ; 4fd800b3a8 2011-02-23 kinaba: long long r2 = LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = ; 4fd800b3a8 2011-02-23 kinaba: long long _ = LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: CASE(6) 4fd800b3a8 2011-02-23 kinaba: string map_[] = ; 4fd800b3a8 2011-02-23 kinaba: vector <string> map(map_, map_+sizeof(map_)/sizeof(*map_)); 4fd800b3a8 2011-02-23 kinaba: long long r1 = LL; 4fd800b3a8 2011-02-23 kinaba: int c1 = ; 4fd800b3a8 2011-02-23 kinaba: long long r2 = LL; 4fd800b3a8 2011-02-23 kinaba: int c2 = ; 4fd800b3a8 2011-02-23 kinaba: long long _ = LL; 4fd800b3a8 2011-02-23 kinaba: END 4fd800b3a8 2011-02-23 kinaba: */ 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: // END CUT HERE