Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem E:
Automotive Navigation

The International Commission for Perfect Cars (ICPC) has constructed a city scale test course for advanced driver assistance systems. Your company, namely the Automotive Control Machines (ACM), is appointed by ICPC to make test runs on the course.

The test course consists of streets, each running straight either east-west or north-south. No streets of the test course have dead ends, that is, at each end of a street, it meets another one. There are no grade separated streets either, and so if a pair of orthogonal streets run through the same geographical location, they always meet at a crossing or a junction, where a car can turn from one to the other. No U-turns are allowed on the test course and a car never moves outside of the streets.

Oops! You have just received an error report telling that the GPS (Global Positioning System) unit of a car running on the test course was broken and the driver got lost. Fortunately, however, the odometer and the electronic compass of the car are still alive.

You are requested to write a program to estimate the current location of the car from available information. You have the car's location just before its GPS unit was broken. Also, you can remotely measure the running distance and the direction of the car once every time unit. The measured direction of the car is one of north, east, south, and west. If you measure the direction of the car while it is making a turn, the measurement result can be the direction either before or after the turn. You can assume that the width of each street is zero.

The car's direction when the GPS unit was broken is not known. You should consider every possible direction consistent with the street on which the car was running at that time.

Input

The input consists of a single test case. The first line contains four integers $n$, $x_0$, $y_0$, $t$, which are the number of streets ($4 \leq n \leq 50$), $x$- and $y$-coordinates of the car at time zero, when the GPS unit was broken, and the current time ($1 \leq t \leq 100$), respectively. $(x_0, y_0)$ is of course on some street. This is followed by $n$ lines, each containing four integers $x_s$, $y_s$, $x_e$, $y_e$ describing a street from $(x_s, y_s)$ to $(x_e, y_e)$ where $(x_s, y_s) \ne (x_e, y_e)$. Since each street runs either east-west or north-south, $x_s = x_e$ or $y_s = y_e$ is also satisfied. You can assume that no two parallel streets overlap or meet. In this coordinate system, the $x$- and $y$-axes point east and north, respectively. Each input coordinate is non-negative and at most 50. Each of the remaining $t$ lines contains an integer $d_i$ ($1 \leq d_i \leq 10$), specifying the measured running distance from time $i − 1$ to $i$, and a letter $c_i$, denoting the measured direction of the car at time $i$ and being either N for north, E for east, W for west, or S for south.

Output

Output all the possible current locations of the car that are consistent with the measurements. If they are $(x_1, y_1),(x_2, y_2), . . . ,(x_p, y_p)$ in the lexicographic order, that is, $x_i < x_j$ or $x_i = x_j$ and $y_i < y_j$ if $1 \leq i < j \leq p$, output the following:

$x_1$ $y_1$

$x_2$ $y_2$

.

.

.

$x_p$ $y_p$

Each output line should consist of two integers separated by a space.

You can assume that at least one location on a street is consistent with the measurements

Sample Input 1

4 2 1 1
1 1 1 2
2 2 2 1
2 2 1 2
1 1 2 1
9 N

Sample Output 1

1 1
2 2

Sample Input 2

6 0 0 2
0 0 2 0
0 1 2 1
0 2 2 2
0 0 0 2
1 0 1 2
2 0 2 2
2 E
7 N

Sample Output 2

0 1
1 0
1 2
2 1

Sample Input 3

7 10 0 1
5 0 10 0
8 5 15 5
5 10 15 10
5 0 5 10
8 5 8 10
10 0 10 10
15 5 15 10
10 N

Sample Output 3

5 5
8 8
10 10
15 5

Solution in Rust (judge verdict: Accepted)

use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::BTreeSet;
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split(' ').map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
enum Road {
    Street {x: i32, low: i32, high: i32},
    Avenue{y:i32, left: i32, right: i32}
}
impl Road {
    fn cross_point(&self, that: Road) -> Option<Position> {
        match (*self, that) {
            (Road::Street{x: x, low: low, high: high}, Road::Avenue{y: y, left: left, right: right}) if low <= y && y <= high && left <= x && x <= right => Some(Position{x: x, y: y}),
            (Road::Avenue{y: y, left: left, right: right}, Road::Street{x: x, low: low, high: high}) if low <= y && y <= high && left <= x && x <= right => Some(Position{x: x, y: y}),
            _ => None
        }
    }
    fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Road {
        if x1 == x2 {
            Road::Street{x: x1, low: min(y1, y2), high: max(y1, y2)}
        }else {
            Road::Avenue{y: y1, left: min(x1, x2), right: max(x1, x2)}
        }
    }
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
enum Dir {
    North, East, South, West
}
impl Dir {
    fn all_dir() -> Vec<Dir> {
        vec![Dir::North, Dir::East, Dir::South, Dir::West]
    }
    fn turn_right(&self) -> Dir {
        match *self {
            Dir::North => Dir::East,
            Dir::East => Dir::South,
            Dir::South => Dir::West,
            Dir::West => Dir::North,
        }
    }
    fn turn_left(&self) -> Dir {
        match *self {
            Dir::North => Dir::West,
            Dir::East => Dir::North,
            Dir::South => Dir::East,
            Dir::West => Dir::South,
        }
    }
    fn is_horizontal(&self) -> bool {
        match *self {
            Dir::West | Dir::East => true,
            _ => false,
        }
    }
    fn is_vertical(&self) -> bool {
        match *self {
            Dir::North | Dir::South => true,
            _ => false,
        }
    }
}
impl FromStr for Dir {
    type Err = ();
    fn from_str(s: &str) -> std::result::Result<Self, <Self as std::str::FromStr>::Err> { 
        match s {
            "N" => Ok(Dir::North),
            "E" => Ok(Dir::East),
            "S" => Ok(Dir::South),
            "W" => Ok(Dir::West),
            _ => Err(()),
        }
    }
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct Position {
    x: i32, y: i32
}
impl Add for Position {
    type Output = Position;
    fn add(self, rhs: Position) -> <Self as std::ops::Add<Position>>::Output { 
        Position{x: self.x + rhs.x, y: self.y + rhs.y}
     }
}
impl Position {
    fn move_to(&self, dir: Dir) -> Position {
        match dir {
            Dir::North => Position{x: self.x, y: self.y + 1},
            Dir::East => Position{x: self.x + 1, y: self.y},
            Dir::South => Position{x: self.x, y: self.y - 1},
            Dir::West => Position{x: self.x - 1, y: self.y},
        }
    }
}
impl PartialOrd for Position {
    fn partial_cmp(&self, rhs: &Position) -> std::option::Option<std::cmp::Ordering> { 
        Some(self.cmp(rhs))
     }
}
impl Ord for Position {
    fn cmp(&self, rhs: &Self) -> std::cmp::Ordering { 
        self.x.cmp(&rhs.x).then(self.y.cmp(&rhs.y))    
    }
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
struct Car {
    position: Position, dir: Dir
}
impl Car {
    fn next_state(&self) -> Car {
        Car{position: self.position.move_to(self.dir), dir: self.dir}
    }
    fn turn(&self) -> Vec<Car> {
        vec![*self, Car{position: self.position, dir: self.dir.turn_left()}, Car{position: self.position, dir: self.dir.turn_right()}]
    }
    fn is_on_road(&self, road: Road) -> bool {
        match road {
            Road::Street{x: x, low: low, high: high} => self.dir.is_vertical() && self.position.x == x && low <= self.position.y && self.position.y <= high ,
            Road::Avenue{y: y, left: left, right: right} => self.dir.is_horizontal() && self.position.y == y && left <= self.position.x && self.position.x <= right,
        }
    }
}

fn main() {
    read!(n: usize, x0: i32, y0: i32, log_count: i32);
    read_map!{
        roads: [{
            read!(x1: i32, y1: i32, x2: i32, y2: i32);
            Road::new(x1, y1, x2, y2)
        }; n]
    }
    let mut cross_point = BTreeSet::new();
    for i in 0 .. n {
        for j in 0 .. i {
            if let Some(cp) = roads[i].cross_point(roads[j]) {
                cross_point.insert(cp);
            }
        }
    }
    freeze!(cross_point);
    let mut current_state = BTreeSet::new();
    for car in Dir::all_dir().into_iter().map(|dir| Car{position: Position{x: x0, y: y0}, dir: dir}) {
        if let Some(road) = roads.iter().find(|&road| car.is_on_road(*road)) {
            current_state.insert((car, road));
        }
    }
    for _ in 0 .. log_count {
        read!(dist: i32, dir: Dir);
        for _ in 1 .. dist {
            let mut next_state = BTreeSet::new();
            for &(car, road) in &current_state {
                let next = car.next_state();
                if !next.is_on_road(*road) {continue;}
                if cross_point.contains(&next.position) {
                    for next in next.turn() {
                        if let Some(road) = roads.iter().find(|&road| next.is_on_road(*road)) {
                            next_state.insert((next, road));
                        }
                    }
                }else {
                    if let Some(road) = roads.iter().find(|&road| next.is_on_road(*road)) {
                        next_state.insert((next, road));
                    }
                }
            }
            current_state = next_state;
        }
        let mut next_state = BTreeSet::new();
        for &(car, road) in &current_state {
            let next = car.next_state();
            if !next.is_on_road(*road){continue;}
            if cross_point.contains(&next.position) {
                for turned in next.turn() {
                    if car.dir != dir && turned.dir != dir {continue;}
                    if let Some(road) = roads.iter().find(|&road| turned.is_on_road(*road)) {
                        let next = turned.next_state();
                        if !next.is_on_road(*road) {continue;}
                        next_state.insert((turned, road));
                    }
                }
            }else if next.dir == dir {
                if let Some(road) = roads.iter().find(|&road| next.is_on_road(*road)) {
                    next_state.insert((next, road));
                }
            }
        }
        current_state = next_state;
    }
    let results = current_state.into_iter().map(|(car, _)| car.position).collect::<BTreeSet<_>>();
    for pos in results {

        println!("{} {}", pos.x, pos.y);
    }
}