http://acm.pku.edu.cn/JudgeOnline/problem?id=1210
Код:
#include <iostream> #include <string> #include <sstream> #include <algorithm> #define N (50) using namespace std; const char *dirname[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }; const char dx[] = { 0, +1, +1, +1, 0, -1, -1, -1 }; const char dy[] = { +1, +1, 0, -1, -1, -1, 0, +1 }; int string2int(const string s, string::const_iterator &p); class car_t { private: int x, y, d; public: car_t(void) { d = -1; } car_t(string line) { istringstream ist(line); string av, st; string::const_iterator dmy; ist >> av >> st; x = string2int(av.substr(1, av.length() - 2), dmy); y = string2int(st.substr(1, st.length() - 2), dmy); if(av[av.length() - 1] == 'W') x = -x; if(st[st.length() - 1] == 'S') y = -y; string dn; ist >> dn; d = find(dirname, dirname + 8, dn) - dirname; } private: static bool throughway(int x, int y, int d) { if(abs(x) % N == 0) { if(dx[d] == 0) return true; } if(abs(y) % N == 0) { if(dy[d] == 0) return true; } if(abs(x) == abs(y)) { if(dx[d] * x == dy[d] * y) return true; } return false; } private: void output(void) { if(throughway(x, y, d)) { cout << "Illegal stopping place" << endl; } else { cout << 'A' << abs(x) << (x < 0 ? 'W' : 'E') << ' '; cout << 'S' << abs(y) << (y < 0 ? 'S' : 'N') << ' '; cout << dirname[d] << endl; } } private: bool parse_stop(istringstream &ist) const { string s; return !(ist >> s); } bool parse_turn(istringstream &ist, int ¶m) const { string s; ist >> s; if(!ist) return false; param = 2; if(s == "HALF" || s == "SHARP") { param += (s[0] == 'H') ? -1 : +1; ist >> s; if(!ist) return false; } if(s == "LEFT" || s == "RIGHT") { param *= (s[0] == 'L') ? -1 : +1; return !(ist >> s); } return false; } bool parse_move(istringstream &ist, int ¶m) const { string s; ist >> s; if(!ist) return false; if(s == "STRAIGHT") { ist >> s; if(!ist) return false; } string::const_iterator p; param = string2int(s, p); if(p != s.end()) return false; return !(ist >> s); } private: void stop(void) { output(); d = -1; } void turn(int param) { int d0 = (d + param + 8) % 8; int x0 = x + dx[d]; int y0 = y + dy[d]; int xx = (x0 + N) % N; int yy = (y0 + N) % N; if(xx != 0 || yy != 0) { if(d0 % 4 == 1 && xx - yy != 0) return; if(d0 % 4 == 3 && xx + yy != N) return; } if(dx[d0] * x0 == N) return; if(dy[d0] * y0 == N) return; bool leave = throughway(x, y, d); bool enter = throughway(x0, y0, d0); if(leave ^ enter) { if((abs(x0) % N != 0 || abs(y0) % N != 0) && param >= -1) return; if((abs(x0) % N != 0 && abs(y0) % N != 0) && param != -3) return; } // accepted x = x0; y = y0; d = d0; } void move(int param) { int x0 = x + dx[d] * param; int y0 = y + dy[d] * param; if(abs(x0) > N || abs(y0) > N) return; if(dx[d] * x0 == N) return; if(dy[d] * y0 == N) return; x += dx[d] * param; y += dy[d] * param; } public: bool stopped(void) const { return d == -1; } void operate(string line) { istringstream ist(line); string s; ist >> s; int param = 0; if(s == "STOP") { if(parse_stop(ist)) stop(); } if(s == "TURN") { if(parse_turn(ist, param)) turn(param); } if(s == "GO") { if(parse_move(ist, param)) move(param); } } }; int string2int(const string s, string::const_iterator &p) { p = s.begin(); int n = 0; while(p != s.end() && isdigit(*p)) { n = n * 10 + (*p - '0'); ++p; } return n; } int main(void) { string line; car_t car; while(getline(cin, line)) { if(line.empty()) continue; if(car.stopped()) { if(line == "END") return 0; car = car_t(line); } else { car.operate(line); } } }