ADDED SRM/556-U/1A.cpp Index: SRM/556-U/1A.cpp ================================================================== --- SRM/556-U/1A.cpp +++ SRM/556-U/1A.cpp @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +class LeftRightDigitsGame2 { public: + string minNumber(string digits, string lowerBound) + { + return rec(digits, lowerBound); + } + + map memo; + string rec(const string& digits, const string& lwb) + { + if(lwb.size() == 0) + return lwb; + if(memo.count(lwb)) + return memo[lwb]; + + string best = (digits.substr(0,lwb.size())>=lwb ? digits.substr(0,lwb.size()) : ""); + string minSoFar = string(1, digits[0]); + for(int t=1; t tail); + if(!needOneMore || incr(target)) { + string m = minNumber(digits, target); + if( m.size() == target.size() ) { + string cand = digits[t] + m + tail; + if( lwb<=cand && (best.empty() || best > cand) ) + best = cand; + } + } + } + else + { + string cand = digits[t] + minSoFar + digits.substr(t+1, lwb.size()-(t+1)); + if( best.empty() || best > cand ) + best = cand; + } + + minSoFar = min(minSoFar+digits[t], digits[t]+minSoFar); + } + return memo[lwb] = best; + } + + bool incr(string& s) + { + for(int i=s.size()-1 ;; --i) + { + if(i==-1) + return false; + if(s[i]<'9') { + s[i]++; + break; + } + s[i]='0'; + } + return true; + } +}; + +// 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 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(_, LeftRightDigitsGame2().minNumber(digits, lowerBound));} +int main(){ + +CASE(0) + string digits = "565"; + string lowerBound = "556"; + string _ = "556"; +END +CASE(1) + string digits = "565"; + string lowerBound = "566"; + string _ = "655"; +END +CASE(2) + string digits = "565"; + string lowerBound = "656"; + string _ = ""; +END +CASE(3) + string digits = "9876543210"; + string lowerBound = "5565565565"; + string _ = "5678943210"; +END +CASE(4) + string digits = "8016352"; + string lowerBound = "1000000"; + string _ = "1086352"; +END +CASE(5) + string digits = "93907757041066207580227527897335194812859183833602"; + string lowerBound = "12089579919698667599337853067564506011831210501927"; + string _ = ""; +END +CASE(6) + string digits = "1"; + string lowerBound = "2"; + string _ = ""; +END +CASE(6) + string digits = "2"; + string lowerBound = "2"; + string _ = "2"; +END +CASE(6) + string digits = "3"; + string lowerBound = "2"; + string _ = "3"; +END +CASE(6) + string digits = "55555555555555555555555555555555555555555555555555"; + string lowerBound = "55555555555555555555555555555555555555555555555555"; + string _ = "55555555555555555555555555555555555555555555555555"; +END +} +// END CUT HERE ADDED SRM/556-U/1B.cpp Index: SRM/556-U/1B.cpp ================================================================== --- SRM/556-U/1B.cpp +++ SRM/556-U/1B.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +class XorTravelingSalesman { public: + int maxProfit(vector cityValues, vector roads) + { + vector< vector > vis(cityValues.size(), vector(1024, false)); + rec(0, cityValues[0], cityValues, roads, vis); + int best = 0; + for(int p=0; p& cityValues, const vector & roads, + vector< vector >& vis) + { + if(vis[p][value]) + return; + vis[p][value] = true; + for(int q=0; q +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(_, XorTravelingSalesman().maxProfit(cityValues, roads));} +int main(){ + +CASE(0) + int cityValues_[] = {0, 7, 11, 5, 2}; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = {"NYNYY", + "YNYNN", + "NYNNN", + "YNNNN", + "YNNNN"}; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = 14; +END +CASE(1) + int cityValues_[] = {556}; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = {"N"}; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = 556; +END +CASE(2) + int cityValues_[] = {0, 4, 8, 32, 512}; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = {"NYYYY", + "YNNNN", + "YNNNN", + "YNNNN", + "YNNNN"}; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = 556; +END +CASE(3) + int cityValues_[] = {37, 1, 19, 64, 42, 41, 64, 64, 54, 16, 256, 36, 64, 2, 4, 2, 62, 29, 58, 64, 1, 32, 16, + 256, 17, 2, 17, 4, 1, 64, 21, 8, 256, 63, 3, 1, 43, 15, 8, 39, 41, 8, 16, 8, 16, 256, 64, 512, 45, 64}; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = {"NNNNNNYYYYNNNNNNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNNNNN", + "NNNNNNNNNNNNNNNNYNNNNNNNYNNNNNNNNNNNNNNNNYYNNNYYNN", + "NNNNNYYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", + "NNNNNNNYNNNNNNNNNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", + "NNNNNNNNNNNNNNNYNNYNYNNNNNNYNNNNNNNNNNYNNNNNNNNNNN", + "NNYNNNYNNNNNNNNYNNYNNNYYNNNYNYNNNNYNNNNNNNNYNNNNNN", + "YNYNNYNYNNNNNNNYNNNNNNNNNNNNNNNNNNNYNNNNNNNNYNNYNN", + "YNNYNNYNYNYYNNNNNNNNNNNNNNNNNNNNNNYNNYNNNNNNNNNNNN", + "YNNNNNNYNNNNNNNNNNNNNNYNYNNNNNNNNNNYYYNNNNNNNYNNNY", + "YNNNNNNNNNNNNNNNNYNYNYNYYNNNYNNNNYNNNNNNNNNNNNNNNY", + "NNNNNNNYNNNNYNNNNNNNNYYNNNYYNNNNYNYYNNNNNNNNNNNNNN", + "NNNNNNNYNNNNNNYNNNNYYNNNYNNYYNNNNNNNNNNNNNYNYNNNNN", + "NNNNNNNNNNYNNNNNYNNNNYNNNNNNNNNNYNYNNYNYNNNYNYNNNN", + "NNNNNNNNNNNNNNNYNNNNNNNNNYNNNNNNNNNNNNYNNNNNNNNYNN", + "NNNNNNNNNNNYNNNNNYNYNNYYNNNNNYNNNNNNNNNYNNYNNYNNNN", + "NNNNYYYNNNNNNYNNNYYNNYNNNYNYYNNNNNNNNNYYYNNYNNYNYN", + "NYNNNNNNNNNNYNNNNNNNYNNNYYNNNYNNNNYNNNNNNNNNNNNNNN", + "NNNNNNNNNYNNNNYYNNNNNNYNNNYNNNNNYNNYNYYNNNNYNNNYNN", + "NNNYYYNNNNNNNNNYNNNNNYNYNYNNNNNNNNYNNNNNNNNNNNNNNN", + "NNNNNNNNNYNYNNYNNNNNNYNYYYNNNNNNNNNNNYNNYNNNNNYNNN", + "NNNNYNNNNNNYNNNNYNNNNYNNNYYNNNYNNNYNNNNNNNNNNYNYNY", + "NNNNNNNNNYYNYNNYNNYYYNYNNNNNNNNYNYNNNNNNNNNNYNNNNN", + "NNNNNYNNYNYNNNYNNYNNNYNNNNNNNNNNNYNNYNYNNYNNNNNNNN", + "NNNNNYNNNYNNNNYNNNYYNNNNNNNNNNNNNNNNNNNNNNYNNNYNNN", + "NYNNNNNNYYNYNNNNYNNYNNNNNNNNNNYNNNNNNYNNNYNNYNNNNN", + "NNNNNNNNNNNNNYNYYNYYYNNNNNNYNNNNNNNNNNNYYNNNNNNNYN", + "NNNNNNNNNNYNNNNNNYNNYNNNNNNNNYNNNNYNNNNNNYYNNNNYNN", + "NNNNYYNNNNYYNNNYNNNNNNNNNYNNNYYNYNNNNNNNNNNNNNNNNN", + "NNNNNNNNNYNYNNNYNNNNNNNNNNNNNYNNNNYNNNNNNNNYNNYNYN", + "NNNNNYNNNNNNNNYNYNNNNNNNNNYYYNNNNNNNNYNNNNYNNNNNNN", + "NNNNNNNNNNNNNNNNNNNNYNNNYNNYNNNNNYNNNNNNNNNNNNNNNY", + "NNNNNNNNNNNNNNNNNNNNNYNNNNNNNNNNYNNNNNNNNNYNNNNNNN", + "NNNNNNNNNNYNYNNNNYNNNNNNNNNYNNNYNNNYYNNNNNYNNNYNNN", + "NNNNNNNNNYNNNNNNNNNNNYYNNNNNNNYNNNNNNNYNNYNNNNNNNN", + "NNNNNYNYNNYNYNNNYNYNYNNNNNYNYNNNNNNYYNYNYNYNNNNNYN", + "YNNNNNYNYNYNNNNNNYNNNNNNNNNNNNNNYNYNNNNNYNNYNNNYNN", + "NNNNNNNNYNNNNNNNNNNNNNYNNNNNNNNNYNYNNNNNNYNNNNNNYN", + "NNNNNNNYYNNNYNNNNYNYNNNNYNNNNYNNNNNNNNNNNYNNNNYNNN", + "NNNNYNNNNNNNNYNYNYNNNNYNNNNNNNNNNYYNNNNYNNNNNNNNNY", + "NNNNNNNNNNNNYNYYNNNNNNNNNYNNNNNNNNNNNNYNNNNNYNYYNN", + "NNNNNNNNNNNNNNNYNNNYNNNNNYNNNNNNNNYYNNNNNNNNNNNNNN", + "NYNNNNNNNNNNNNNNNNNNNNYNYNYNNNNNNYNNYYNNNNNNNNNNNN", + "NYNNNNNNNNNYNNYNNNNNNNNYNNYNNYNYYNYNNNNNNNNNYNNNNN", + "NNNNNYNNNNNNYNNYNYNNNNNNNNNNYNNNNNNYNNNNNNNNNNNNNY", + "NNNNNNYNNNNYNNNNNNNNNYNNYNNNNNNNNNNNNNNYNNYNNYNNNY", + "NNNNNNNNYNNNYNYNNNNNYNNNNNNNNNNNNNNNNNNNNNNNYNNNNN", + "NYNNNNNNNNNNNNNYNNNYNNNYNNNNYNNNYNNNNYNYNNNNNNNNNN", + "NYNNNNYNNNNNNYNNNYNNYNNNNNYNNNNNNNNYNNNYNNNNNNNNNN", + "NNNNNNNNNNNNNNNYNNNNNNNNNYNNYNNNNNYNYNNNNNNNNNNNNN", + "NNNNNNNNYYNNNNNNNNNNYNNNNNNNNNYNNNNNNNYNNNNYYNNNNN"}; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = 895; +END +/* +CASE(4) + int cityValues_[] = ; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = ; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = ; +END +CASE(5) + int cityValues_[] = ; + vector cityValues(cityValues_, cityValues_+sizeof(cityValues_)/sizeof(*cityValues_)); + string roads_[] = ; + vector roads(roads_, roads_+sizeof(roads_)/sizeof(*roads_)); + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/556-U/1C-U.cpp Index: SRM/556-U/1C-U.cpp ================================================================== --- SRM/556-U/1C-U.cpp +++ SRM/556-U/1C-U.cpp @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +template +class IdGen +{ + map v2id_; + vector id2v_; +public: + int v2id(const T& v) { + if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } + return v2id_[v]; + } + const T& id2v(int i) const { return id2v_[i]; } + int size() const { return id2v_.size(); } +}; + +template +class MaxFlow +{ + IdGen idgen; + vector G[NV]; + Flow F[NV][NV]; + +public: + void addEdge( Vert s_, Vert t_, Flow f ) + { + const int s = idgen.v2id(s_), t = idgen.v2id(t_); + G[s].push_back(t); + G[t].push_back(s); + F[s][t] = f; + F[t][s] = 0; + } + + Flow calc( Vert s_, Vert t_ ) + { + const int S = idgen.v2id(s_), D = idgen.v2id(t_); + for( Flow total=0 ;; ) { + // Do BFS and compute the level for each node. + int LV[NV] = {0}; + vector Q(1, S); + for(int lv=1; !Q.empty(); ++lv) { + vector Q2; + for(size_t i=0; i!=Q.size(); ++i) { + const vector& ne = G[Q[i]]; + for(size_t j=0; j!=ne.size(); ++j) + if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) + LV[ne[j]]=lv, Q2.push_back(ne[j]); + } + Q.swap(Q2); + } + + // Destination is now unreachable. Done. + if( !LV[D] ) + return total; + + // Iterating DFS. + bool blocked[NV] = {}; + total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); + } + } + +private: + Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) + { + Flow flow_out = 0; + for(size_t i=0; i!=G[v].size(); ++i) { + int u = G[v][i]; + if( LV[v]+1==LV[u] && F[v][u] ) { + Flow f = min(flow_in-flow_out, F[v][u]); + if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) { + F[v][u] -= f; + F[u][v] += f; + flow_out += f; + if( flow_in == flow_out ) return flow_out; + } + } + } + blocked[v] = (flow_out==0); + return flow_out; + } +}; + +class OldBridges { public: + string isPossible(vector bridges, int a1, int a2, int an, int b1, int b2, int bn) + { + typedef pair Vert; + enum {SRC, SINK, VERT, E1, E2}; + static const int INF = 99999999; + MaxFlow* mf = new MaxFlow; + + mf->addEdge(Vert(SRC,0), Vert(VERT,a1), 2*an); + mf->addEdge(Vert(VERT,a2), Vert(SINK,0), 2*an); + mf->addEdge(Vert(SRC,0), Vert(VERT,b1), 2*bn); + mf->addEdge(Vert(VERT,b2), Vert(SINK,0), 2*bn); + + int N = bridges.size(); + for(int a=0; aaddEdge(Vert(VERT,a), Vert(VERT,b), INF); + mf->addEdge(Vert(VERT,b), Vert(VERT,a), INF); + } else if(bridges[a][b] == 'O') { + Vert e1 = Vert(E1, a*N+b); + Vert e2 = Vert(E2, a*N+b); + mf->addEdge(Vert(VERT,a), e1, 2); + mf->addEdge(Vert(VERT,b), e1, 2); + mf->addEdge(e1, e2, 2); + mf->addEdge(e2, Vert(VERT,a), 2); + mf->addEdge(e2, Vert(VERT,b), 2); + } + + int flow = mf->calc(Vert(SRC,0), Vert(SINK,0)); + delete mf; + return flow==(an+an+bn+bn) ? "Yes" : "No"; + } +}; + +// 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 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(_, OldBridges().isPossible(bridges, a1, a2, an, b1, b2, bn));} +int main(){ + +CASE(0) + string bridges_[] = {"XOXX","OXOX","XOXO","XXOX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 1; + int an = 1; + int b1 = 2; + int b2 = 3; + int bn = 1; + string _ = "Yes"; +END +CASE(1) + string bridges_[] = {"XOXX","OXOX","XOXO","XXOX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 2; + int an = 1; + int b1 = 1; + int b2 = 3; + int bn = 1; + string _ = "No"; +END +CASE(2) + string bridges_[] = {"XOXO","OXOX","XOXO","OXOX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 2; + int an = 1; + int b1 = 1; + int b2 = 3; + int bn = 1; + string _ = "Yes"; +END +CASE(3) + string bridges_[] = {"XNXO","NXOX","XOXO","OXOX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 2; + int an = 1; + int b1 = 1; + int b2 = 3; + int bn = 2; + string _ = "No"; +END +CASE(4) + string bridges_[] = {"XOXOO","OXOXO","XOXOO","OXOXO","OOOOX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 2; + int an = 2; + int b1 = 1; + int b2 = 3; + int bn = 2; + string _ = "Yes"; +END +CASE(5) + string bridges_[] = {"XOOOX","OXOOX","OOXOX","OOOXN","XXXNX"}; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = 0; + int a2 = 4; + int an = 3; + int b1 = 1; + int b2 = 2; + int bn = 2; + string _ = "No"; +END +/* +CASE(6) + string bridges_[] = ; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = ; + int a2 = ; + int an = ; + int b1 = ; + int b2 = ; + int bn = ; + string _ = ; +END +CASE(7) + string bridges_[] = ; + vector bridges(bridges_, bridges_+sizeof(bridges_)/sizeof(*bridges_)); + int a1 = ; + int a2 = ; + int an = ; + int b1 = ; + int b2 = ; + int bn = ; + string _ = ; +END +*/ +} +// END CUT HERE