76db68d634 2018-07-28 kinaba: #include <iostream> 76db68d634 2018-07-28 kinaba: #include <sstream> 76db68d634 2018-07-28 kinaba: #include <iomanip> 76db68d634 2018-07-28 kinaba: #include <vector> 76db68d634 2018-07-28 kinaba: #include <string> 76db68d634 2018-07-28 kinaba: #include <map> 76db68d634 2018-07-28 kinaba: #include <unordered_map> 76db68d634 2018-07-28 kinaba: #include <set> 76db68d634 2018-07-28 kinaba: #include <algorithm> 76db68d634 2018-07-28 kinaba: #include <numeric> 76db68d634 2018-07-28 kinaba: #include <iterator> 76db68d634 2018-07-28 kinaba: #include <functional> 76db68d634 2018-07-28 kinaba: #include <complex> 76db68d634 2018-07-28 kinaba: #include <queue> 76db68d634 2018-07-28 kinaba: #include <stack> 76db68d634 2018-07-28 kinaba: #include <cmath> 76db68d634 2018-07-28 kinaba: #include <cassert> 76db68d634 2018-07-28 kinaba: #include <tuple> 76db68d634 2018-07-28 kinaba: using namespace std; 76db68d634 2018-07-28 kinaba: typedef long long LL; 76db68d634 2018-07-28 kinaba: typedef complex<double> CMP; 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: class PolylineAreas { public: 76db68d634 2018-07-28 kinaba: vector<long long> findAreas(string polyline) 76db68d634 2018-07-28 kinaba: { 76db68d634 2018-07-28 kinaba: string cmd; 76db68d634 2018-07-28 kinaba: { 76db68d634 2018-07-28 kinaba: const char* p = polyline.c_str(); 76db68d634 2018-07-28 kinaba: while (*p) 76db68d634 2018-07-28 kinaba: parse_one(p, cmd); 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: #define enc(x,y) ((LL(x+1000000)<<32)|(y+1000000)) 76db68d634 2018-07-28 kinaba: const int dx[] = { 1, 0, -1, 0 }; 76db68d634 2018-07-28 kinaba: const int dy[] = { 0, 1, 0, -1 }; 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: unordered_map<LL, int> edge; 76db68d634 2018-07-28 kinaba: { 76db68d634 2018-07-28 kinaba: int x = 0, y = 0, d = 0; 76db68d634 2018-07-28 kinaba: for (int ch : cmd) { 76db68d634 2018-07-28 kinaba: switch (ch) { 76db68d634 2018-07-28 kinaba: case 'F': { 76db68d634 2018-07-28 kinaba: LL p = enc(x, y); 76db68d634 2018-07-28 kinaba: x += dx[d]; 76db68d634 2018-07-28 kinaba: y += dy[d]; 76db68d634 2018-07-28 kinaba: LL c = enc(x, y); 76db68d634 2018-07-28 kinaba: edge[p] |= 1 << d; 76db68d634 2018-07-28 kinaba: edge[c] |= 1 << ((d + 2) % 4); 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: break; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: case 'L': d = (d + 1) % 4; break; 76db68d634 2018-07-28 kinaba: case 'R': d = (d + 3) % 4; break; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: vector<LL> ans; 76db68d634 2018-07-28 kinaba: { 76db68d634 2018-07-28 kinaba: for (auto pd : edge) { 76db68d634 2018-07-28 kinaba: const int s_x = int(pd.first >> 32) - 1000000; 76db68d634 2018-07-28 kinaba: const int s_y = int(pd.first & 0xffffffff) - 1000000; 76db68d634 2018-07-28 kinaba: int& ds = pd.second; 76db68d634 2018-07-28 kinaba: for (int d = 0; d < 4; ++d) if (ds&(1 << d)) { 76db68d634 2018-07-28 kinaba: // go clockwise from (x,y) -> d 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: LL area = 0; 76db68d634 2018-07-28 kinaba: int x = s_x, y = s_y; 76db68d634 2018-07-28 kinaba: do { 76db68d634 2018-07-28 kinaba: //cerr << "(" << x << "," << y << "): " << d << endl; 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: // move 76db68d634 2018-07-28 kinaba: int px = x, py = y; 76db68d634 2018-07-28 kinaba: x += dx[d]; 76db68d634 2018-07-28 kinaba: y += dy[d]; 76db68d634 2018-07-28 kinaba: edge[enc(px, py)] &= ~(1 << d); 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: // turn 76db68d634 2018-07-28 kinaba: int& dd = edge[enc(x, y)]; 76db68d634 2018-07-28 kinaba: if (dd & (1 << ((d + 3) % 4))) 76db68d634 2018-07-28 kinaba: d = (d + 3) % 4; 76db68d634 2018-07-28 kinaba: else if (dd & (1 << d)) 76db68d634 2018-07-28 kinaba: ; 76db68d634 2018-07-28 kinaba: else if (dd & (1 << ((d + 1) % 4))) 76db68d634 2018-07-28 kinaba: d = (d + 1) % 4; 76db68d634 2018-07-28 kinaba: else if (dd & (1 << ((d + 2)%4))) 76db68d634 2018-07-28 kinaba: d = (d + 2) % 4; 76db68d634 2018-07-28 kinaba: else 76db68d634 2018-07-28 kinaba: break; 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: // calc area 76db68d634 2018-07-28 kinaba: area += LL(x - s_x)*(py - s_y) - LL(px-s_x)*(y-s_y); 76db68d634 2018-07-28 kinaba: //cerr << LL(x - s_x)*(py - s_y) - LL(px - s_x)*(y - s_y) << endl; 76db68d634 2018-07-28 kinaba: } while (x != s_x || y != s_y); 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: if(x==s_x && y==s_y && area > 0) 76db68d634 2018-07-28 kinaba: ans.push_back(area/2); 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: sort(ans.begin(), ans.end()); 76db68d634 2018-07-28 kinaba: if (ans.size() > 200) { 76db68d634 2018-07-28 kinaba: vector<LL> a2(ans.begin(), ans.begin() + 100); 76db68d634 2018-07-28 kinaba: a2.insert(a2.end(), ans.end() - 100, ans.end()); 76db68d634 2018-07-28 kinaba: return a2; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: return ans; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: void parse_one(const char*& p, string& buf) { 76db68d634 2018-07-28 kinaba: if ('0' <= *p && *p <= '9') { 76db68d634 2018-07-28 kinaba: int rep = (*p++ - '0'); 76db68d634 2018-07-28 kinaba: while('0' <= *p && *p <= '9') 76db68d634 2018-07-28 kinaba: rep = rep*10 + (*p++ - '0'); 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: string sub; 76db68d634 2018-07-28 kinaba: parse_one(p, sub); 76db68d634 2018-07-28 kinaba: while (rep-- > 0) 76db68d634 2018-07-28 kinaba: buf += sub; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: else if (*p == '[') { 76db68d634 2018-07-28 kinaba: for (++p; *p != ']'; ) 76db68d634 2018-07-28 kinaba: parse_one(p, buf); 76db68d634 2018-07-28 kinaba: ++p; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: else { 76db68d634 2018-07-28 kinaba: buf += *p++; 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: }; 76db68d634 2018-07-28 kinaba: 76db68d634 2018-07-28 kinaba: // BEGIN CUT HERE 76db68d634 2018-07-28 kinaba: #include <ctime> 76db68d634 2018-07-28 kinaba: double start_time; string timer() 76db68d634 2018-07-28 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 76db68d634 2018-07-28 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 76db68d634 2018-07-28 kinaba: { os << "{ "; 76db68d634 2018-07-28 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 76db68d634 2018-07-28 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 76db68d634 2018-07-28 kinaba: void verify_case(const vector<long long>& Expected, const vector<long long>& Received) { 76db68d634 2018-07-28 kinaba: bool ok = (Expected == Received); 76db68d634 2018-07-28 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 76db68d634 2018-07-28 kinaba: cerr << "\to: " << Expected << endl << "\tx: " << Received << endl; } } 76db68d634 2018-07-28 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 76db68d634 2018-07-28 kinaba: #define END verify_case(_, PolylineAreas().findAreas(polyline));} 76db68d634 2018-07-28 kinaba: int main(){ 76db68d634 2018-07-28 kinaba: CASE(0) 76db68d634 2018-07-28 kinaba: string polyline = "FRFLF"; 76db68d634 2018-07-28 kinaba: vector<long long> _; 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(1) 76db68d634 2018-07-28 kinaba: string polyline = "4[100FR]"; 76db68d634 2018-07-28 kinaba: long long __[] = {10000 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(2) 76db68d634 2018-07-28 kinaba: string polyline = "2[2[100FR]]"; 76db68d634 2018-07-28 kinaba: long long __[] = {10000 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(3) 76db68d634 2018-07-28 kinaba: string polyline = "47[100FR]"; 76db68d634 2018-07-28 kinaba: long long __[] = {10000 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(4) 76db68d634 2018-07-28 kinaba: string polyline = "1000000[]"; 76db68d634 2018-07-28 kinaba: vector<long long> _; 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(5) 76db68d634 2018-07-28 kinaba: string polyline = "4[6FR]FR6FL2FL6FR3FRFR6FL2FL6F"; 76db68d634 2018-07-28 kinaba: long long __[] = {1, 2, 2, 3, 3, 4, 6, 6, 9 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(6) 76db68d634 2018-07-28 kinaba: string polyline = "4[6FR]FR6FL2FL6FR3FRFR6FL2FL4F"; 76db68d634 2018-07-28 kinaba: long long __[] = {1, 2, 2, 3, 3, 4, 6, 15 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(7) 76db68d634 2018-07-28 kinaba: string polyline = "3FRFRFLFLFRFR3FRFRFLFLFRF"; 76db68d634 2018-07-28 kinaba: long long __[] = {7 }; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: CASE(8) 76db68d634 2018-07-28 kinaba: string polyline = "250000F"; 76db68d634 2018-07-28 kinaba: long long __[] = {-1}; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: /* 76db68d634 2018-07-28 kinaba: CASE(9) 76db68d634 2018-07-28 kinaba: string polyline = ; 76db68d634 2018-07-28 kinaba: long long __[] = ; 76db68d634 2018-07-28 kinaba: vector<long long> _(__, __+sizeof(__)/sizeof(*__)); 76db68d634 2018-07-28 kinaba: END 76db68d634 2018-07-28 kinaba: */ 76db68d634 2018-07-28 kinaba: } 76db68d634 2018-07-28 kinaba: // END CUT HERE