ADDED SRM/TCO18-3B-U/1A.cpp Index: SRM/TCO18-3B-U/1A.cpp ================================================================== --- SRM/TCO18-3B-U/1A.cpp +++ SRM/TCO18-3B-U/1A.cpp @@ -0,0 +1,127 @@ +#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 SquareCutout { public: + int verify(vector cutout) + { + const int Y = cutout.size(), X = cutout[0].size(); + + bool has_black = false; + for (int y = 0; y < Y; ++y) + for (int x = 0; x < X; ++x) + if (cutout[y][x] == '#') + has_black = true; + if (!has_black) + return 1; + + int ym = Y, xm = X, yM = 0, xM = 0; + for (int y = 0; y < Y; ++y) + for (int x = 0; x < X; ++x) + if (cutout[y][x] == '#') + ym = min(ym, y), yM = max(yM, y), xm = min(xm, x), xM = max(xM, x); + + for (int y = ym; y <= yM; ++y) + for (int x = xm; x <= xM; ++x) + if (cutout[y][x] != '#') + return 0; + + bool x_extendable = (xm == 0 || xM == X - 1); + bool y_extendable = (ym == 0 || yM == Y - 1); + int yy = yM - ym + 1; + int xx = xM - xm + 1; + if (yy == xx) + return yy; + if (yy < xx) + return y_extendable ? xx : 0; + return x_extendable ? yy : 0; + } +}; + +// 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(_, SquareCutout().verify(cutout));} +int main(){ + +CASE(0) + string cutout_[] = {".....", + "..##.", + "..##.", + ".....", + "....."}; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 2; +END +CASE(1) + string cutout_[] = {"...", + "..."}; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 1; +END +CASE(2) + string cutout_[] = {".....", + ".###.", + ".#.#.", + ".###.", + "....."}; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 0; +END +CASE(3) + string cutout_[] = {"..####", + "..####", + "......"}; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 4; +END +CASE(4) + string cutout_[] = {"..#..", + ".###.", + "#####", + ".###.", + "..#.."}; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 0; +END +CASE(5) +string cutout_[] = { "...", "...", "..." }; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = 1; +END +/* +CASE(6) + string cutout_[] = ; + vector cutout(cutout_, cutout_+sizeof(cutout_)/sizeof(*cutout_)); + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/TCO18-3B-U/1B.cpp Index: SRM/TCO18-3B-U/1B.cpp ================================================================== --- SRM/TCO18-3B-U/1B.cpp +++ SRM/TCO18-3B-U/1B.cpp @@ -0,0 +1,138 @@ +#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 TestProctoring { public: + double expectedTime(vector p, vector q) + { + const int N = p.size(); + vector dp(1<= 0; --i) + if (i == N) + dp2[(i << N) | mask] = dp[mask]; + else if ((mask&(1 << i)) == 0) + dp2[(i << N) | mask] = dp2[((i + 1) << N) | mask]; + else { + double e1 = dp2[((i + 1) << N) | mask &~(1 << i)]; + double e2 = dp2[((i + 1) << N) | mask]; + dp2[(i << N) | mask] = (p[i] * e1 + (q[i] - p[i])*e2) / q[i]; + } + + double pp = 1.0; + for (int i = 0; i= 0; --i) + if (i == N) + dp2[(i << N) | mask] = dp[mask]; + else if ((mask&(1 << i)) == 0) + dp2[(i << N) | mask] = dp2[((i + 1) << N) | mask]; + else { + double e1 = dp2[((i + 1) << N) | mask &~(1 << i)]; + double e2 = dp2[((i + 1) << N) | mask]; + dp2[(i << N) | mask] = (p[i] * e1 + (q[i] - p[i])*e2) / q[i]; + } + } + + return dp[(1< +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 double& Expected, const double& Received) { + bool ok = (abs(Expected - Received)/abs(Expected) < 1e-6); + 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(_, TestProctoring().expectedTime(p, q));} +int main(){ +CASE(0) + int p_[] = {2}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {4}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 2.0; +END +CASE(1) + int p_[] = {1,2}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {2,4}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 2.6666666666666665; +END +CASE(2) + int p_[] = {3,1,2,4,2,5}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {3,1,2,4,2,5}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 1.0; +END +CASE(3) + int p_[] = {1,1,1,1,1,1,1,1}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {1,2,3,4,5,6,7,8}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 13.604834665120991; +END +CASE(4) + int p_[] = {2,3,5,7,11,13,17}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {3,5,7,11,13,17,19}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 2.6299445065924276; +END +CASE(5) + int p_[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = {1000000000,1000000000,1000000000,1000000000,1000000000, +1000000000,1000000000,1000000000,1000000000,1000000000, +1000000000,1000000000,1000000000,1000000000,1000000000, +1000000000,1000000000,1000000000,1000000000,1000000000}; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = 3.597740924491638E9; +END +/* +CASE(6) + int p_[] = ; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = ; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = ; +END +CASE(7) + int p_[] = ; + vector p(p_, p_+sizeof(p_)/sizeof(*p_)); + int q_[] = ; + vector q(q_, q_+sizeof(q_)/sizeof(*q_)); + double _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/TCO18-4-U/1A.cpp Index: SRM/TCO18-4-U/1A.cpp ================================================================== --- SRM/TCO18-4-U/1A.cpp +++ SRM/TCO18-4-U/1A.cpp @@ -0,0 +1,122 @@ +#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; + +static const unsigned MODVAL = 1000000007; + +template +struct DP2 +{ + const int N1, N2; + vector data; + DP2(int N1, int N2, const T& t = T()) + : N1(N1), N2(N2), data(N1*N2, t) { + assert(data.size() * sizeof(T)<(1 << 28)); + } + T& operator()(int i1, int i2) + { + return data[(i1*N2) + i2]; + } + void swap(DP2& rhs) + { + data.swap(rhs.data); + } +}; + +class SumPyramid { public: + int countPyramids(int levels, int top) + { + vector C(1, 1); + for (int _ = 1; _ < levels; ++_) { + vector CC(C.size() + 1); + for (size_t i = 0; i < CC.size(); ++i) + CC[i] = min(top + 1, (i ? C[i - 1] : 0) + (i memo(levels, top+1, -1); + return rec(levels - 1, 0, top, C, memo); + } + + int rec(int n, int k, int sum, const vector& C, DP2& memo) + { + // #{x,y,..,z} where nCk x + nC{k+1} y + ... + nCn z == sum + if (memo(k, sum) != -1) + return memo(k, sum); + + if (k == n) + return memo(k, sum) = 1; + int ans = 0; + for (int v = 0; v*C[k] <= sum; ++v) + ans = (ans + rec(n, k+1, sum - v*C[k], C, memo)) % MODVAL; + return memo(k, sum) = ans; + } +}; + +// 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(_, SumPyramid().countPyramids(levels, top));} +int main(){ + +CASE(0) + int levels = 1; + int top = 47; + int _ = 1; +END +CASE(1) + int levels = 2; + int top = 10; + int _ = 11; +END +CASE(2) + int levels = 3; + int top = 2; + int _ = 4; +END +CASE(3) + int levels = 5; + int top = 7; + int _ = 18; +END +CASE(4) + int levels = 1000; + int top = 1000; + int _ = -1; +END +/* +CASE(5) + int levels = ; + int top = ; + int _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/TCO18-4-U/1B-U.cpp Index: SRM/TCO18-4-U/1B-U.cpp ================================================================== --- SRM/TCO18-4-U/1B-U.cpp +++ SRM/TCO18-4-U/1B-U.cpp @@ -0,0 +1,199 @@ +#include +#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 PolylineAreas { public: + vector findAreas(string polyline) + { + string cmd; + { + const char* p = polyline.c_str(); + while (*p) + parse_one(p, cmd); + } + + #define enc(x,y) ((LL(x+1000000)<<32)|(y+1000000)) + const int dx[] = { 1, 0, -1, 0 }; + const int dy[] = { 0, 1, 0, -1 }; + + unordered_map edge; + { + int x = 0, y = 0, d = 0; + for (int ch : cmd) { + switch (ch) { + case 'F': { + LL p = enc(x, y); + x += dx[d]; + y += dy[d]; + LL c = enc(x, y); + edge[p] |= 1 << d; + edge[c] |= 1 << ((d + 2) % 4); + + break; + } + case 'L': d = (d + 1) % 4; break; + case 'R': d = (d + 3) % 4; break; + } + } + } + + vector ans; + { + for (auto pd : edge) { + const int s_x = int(pd.first >> 32) - 1000000; + const int s_y = int(pd.first & 0xffffffff) - 1000000; + int& ds = pd.second; + for (int d = 0; d < 4; ++d) if (ds&(1 << d)) { + // go clockwise from (x,y) -> d + + LL area = 0; + int x = s_x, y = s_y; + do { + //cerr << "(" << x << "," << y << "): " << d << endl; + + // move + int px = x, py = y; + x += dx[d]; + y += dy[d]; + edge[enc(px, py)] &= ~(1 << d); + + // turn + int& dd = edge[enc(x, y)]; + if (dd & (1 << ((d + 3) % 4))) + d = (d + 3) % 4; + else if (dd & (1 << d)) + ; + else if (dd & (1 << ((d + 1) % 4))) + d = (d + 1) % 4; + else if (dd & (1 << ((d + 2)%4))) + d = (d + 2) % 4; + else + break; + + // calc area + area += LL(x - s_x)*(py - s_y) - LL(px-s_x)*(y-s_y); + //cerr << LL(x - s_x)*(py - s_y) - LL(px - s_x)*(y - s_y) << endl; + } while (x != s_x || y != s_y); + + if(x==s_x && y==s_y && area > 0) + ans.push_back(area/2); + } + } + } + + sort(ans.begin(), ans.end()); + if (ans.size() > 200) { + vector a2(ans.begin(), ans.begin() + 100); + a2.insert(a2.end(), ans.end() - 100, ans.end()); + return a2; + } + return ans; + } + + void parse_one(const char*& p, string& buf) { + if ('0' <= *p && *p <= '9') { + int rep = (*p++ - '0'); + while('0' <= *p && *p <= '9') + rep = rep*10 + (*p++ - '0'); + + string sub; + parse_one(p, sub); + while (rep-- > 0) + buf += sub; + } + else if (*p == '[') { + for (++p; *p != ']'; ) + parse_one(p, buf); + ++p; + } + else { + buf += *p++; + } + } +}; + +// 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 vector& Expected, const vector& 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(_, PolylineAreas().findAreas(polyline));} +int main(){ +CASE(0) + string polyline = "FRFLF"; + vector _; +END +CASE(1) + string polyline = "4[100FR]"; + long long __[] = {10000 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(2) + string polyline = "2[2[100FR]]"; + long long __[] = {10000 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(3) + string polyline = "47[100FR]"; + long long __[] = {10000 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(4) + string polyline = "1000000[]"; + vector _; +END +CASE(5) + string polyline = "4[6FR]FR6FL2FL6FR3FRFR6FL2FL6F"; + long long __[] = {1, 2, 2, 3, 3, 4, 6, 6, 9 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(6) + string polyline = "4[6FR]FR6FL2FL6FR3FRFR6FL2FL4F"; + long long __[] = {1, 2, 2, 3, 3, 4, 6, 15 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(7) + string polyline = "3FRFRFLFLFRFR3FRFRFLFLFRF"; + long long __[] = {7 }; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +CASE(8) + string polyline = "250000F"; + long long __[] = {-1}; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +/* +CASE(9) + string polyline = ; + long long __[] = ; + vector _(__, __+sizeof(__)/sizeof(*__)); +END +*/ +} +// END CUT HERE