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);
}
}
}