#include #include #include #include #include #include #include #include using namespace std; #define for if(0);else for typedef pair point; typedef vector env_t; class expr { // base public: virtual bool exec() const = 0; }; class expr_varref : public expr { private: const env_t& env; int idx; public: expr_varref(const env_t& env, int idx) : env(env), idx(idx) {} bool exec() const { return env[idx]; } }; class expr_true : public expr { public: bool exec() const { return true; } }; class expr_false : public expr { public: bool exec() const { return false; } }; class expr_not : public expr { private: const expr *child; public: expr_not(const expr *child) : child(child) {} bool exec() const { return ! child->exec(); } }; class expr_and : public expr { private: const expr *c1, *c2; public: expr_and(const expr *c1, const expr *c2) : c1(c1), c2(c2) {} bool exec() const { return c1->exec() && c2->exec(); } }; class expr_or : public expr { private: const expr *c1, *c2; public: expr_or(const expr *c1, const expr *c2) : c1(c1), c2(c2) {} bool exec() const { return c1->exec() || c2->exec(); } }; enum TokenType { TTRUE, FFALSE, TVAR, LAND, LNOT, LOR, LPAREN, RPAREN, EOL }; struct token { TokenType type; int idx; // TVAR token(TokenType type = EOL) : type(type), idx(0) {} token(char varname) : type(TVAR), idx((0xFF & varname) - 'A') {} }; // expr. static env_t vars(26, false); static string str; static int cursor; static token adv; static token readToken() { while(cursor < str.size() && str[cursor] == ' ') cursor++; if(cursor >= str.size()) return token(EOL); switch(str[cursor]) { case '(': cursor++; return token(LPAREN); case ')': cursor++; return token(RPAREN); } int endpos = cursor; while(endpos < str.size() && isalpha(str[endpos])) endpos++; const string ss = str.substr(cursor, endpos - cursor); cursor = endpos; if(ss == "TRUE") return token(TTRUE); else if(ss == "FALSE") return token(FFALSE); else if(ss == "NOT") return token(LNOT); else if(ss == "AND") return token(LAND); else if(ss == "OR") return token(LOR); //assert(ss.size() == 1); return token(ss[0]); } #define EAT adv = readToken static expr *E(); static expr *V() { switch(adv.type) { case TTRUE: EAT(); return new expr_true(); case FFALSE: EAT(); return new expr_false(); case TVAR: { int idx = adv.idx; EAT(); return new expr_varref(vars, idx); } case LPAREN: { EAT(); expr *e = E(); //assert(adv.type == RPAREN); EAT(); return e; } } //assert(false); return NULL; } static expr *T() { bool not_exist = false; while(adv.type == LNOT) { not_exist = !not_exist; EAT(); } expr *e = V(); if(not_exist) return new expr_not(e); else return e; } static expr *F() { expr *e1 = T(); while(adv.type == LAND) { EAT(); e1 = new expr_and(e1, T()); } return e1; } static expr *E() { expr *e1 = F(); while(adv.type == LOR) { EAT(); e1 = new expr_or(e1, F()); } return e1; } static expr *parse() { EAT(); return E(); } struct obj { bool fork; point pos; int idx; obj() {} obj(point pos) : fork(true), pos(pos), idx(-1) {} obj(point pos, char varname) : fork(false), pos(pos), idx(varname - 'A') {} }; int real(const pair& p) { return p.first; } int imag(const pair& p) { return p.second; } pair& operator += (pair& a, const pair& b) { return a = make_pair(a.first + b.first, a.second + b.second); } void solve(int N, const vector& objs, const expr *e) { point pos(0, 0), dir(1, 0); vector l(objs.size(), -1), r(objs.size(), -1); vector d(objs.size(), -1), u(objs.size(), -1); for(int i = 0; i < objs.size(); i++) { point p = objs[i].pos; int rmin = INT_MAX, umin = INT_MAX; int ridx = -1, uidx = -1; for(int j = 0; j < objs.size(); j++) { if(i == j) continue; if(real(p) == real(objs[j].pos) && imag(objs[j].pos) > imag(p)) { // u cand. if(imag(objs[j].pos) < umin) umin = imag(objs[uidx = j].pos); } if(imag(p) == imag(objs[j].pos) && real(objs[j].pos) > real(p)) { // r cand. if(real(objs[j].pos) < rmin) rmin = real(objs[ridx = j].pos); } } if(ridx >= 0) { r[i] = ridx; if(l[ridx] < 0 || real(p) > real(objs[l[ridx]].pos)) l[ridx] = i; } if(uidx >= 0) { u[i] = uidx; if(d[uidx] < 0 || imag(p) > imag(objs[d[uidx]].pos)) d[uidx] = i; } } int cs = -1, minx = INT_MAX; for(int i = 0; i < objs.size(); i++) { if(imag(objs[i].pos) == 0 && real(objs[i].pos) >= 0 && real(objs[i].pos) < minx) minx = real(objs[cs = i].pos); } while(cs >= 0) { const obj& o = objs[cs]; do { cout << real(pos) << ' ' << imag(pos) << endl; pos += dir; } while(pos != o.pos); //cout << real(o.pos) << ' ' << imag(o.pos) << endl; if(o.fork) { pos = o.pos; if(e->exec()) dir = point(dir.second, -dir.first); else dir = point(-dir.second, dir.first); } else { vars[o.idx] = !vars[o.idx]; } if(dir == point(1, 0)) cs = r[cs]; else if(dir == point(-1, 0)) cs = l[cs]; else if(dir == point(0, 1)) cs = u[cs]; else if(dir == point(0, -1)) cs = d[cs]; else ;//assert(false); } do { cout << real(pos) << ' ' << imag(pos) << endl; pos += dir; } while(real(pos) >= -N && real(pos) <= N && imag(pos) >= -N && imag(pos) <= N); } int main() { getline(cin, str); expr *e = parse(); int N, M, K; cin >> N >> M >> K; vector objs; while(M--) { int x, y; cin >> x >> y; objs.push_back(obj(point(x, y))); } while(K--) { int x, y; char c; cin >> x >> y >> c; objs.push_back(obj(point(x, y), c)); } solve(N, objs, e); return 0; }