Analysis: Bovine Ballet by Fatih Gelgi

In this problem, a trivial solution is to keep the feet positions and apply instructions one by one. After each instruction, the corner coordinates of the rectangular stage are updated. Note that we cannot mark the feet position on a matrix since the matrix may be excessively large and doesn't fit in the memory (ex. an input that has 500 FRFs and FRP,RRP alternates 250 times).

at the beginning, we need to assign initial positions to the feet. Let's say:

```    y x
FL (0,0)
FR (0,1)
RL (1,0)
RR (1,1)
```

Without rotation, moves are straightforward:

• forward: y=y-1
• right: x=x+1
• back: y=y+1
• left: x=x-1

When we include rotation, the moves will change with respect to the current direction. We have 16 different cases in total -- 4 moves per direction. One idea is to write all cases one by one. However, we will work on a more elegant idea. Let's numerate the moves first - {0:forward, 1:right, 2:back, 3:left}. Notice that they in clockwise order. Let's numerate the directions again in clockwise order as the second step - {0:north, 1:east, 2:south, 3:west}. Now, consider the following instructions:

```0) Initially:
.. .. .. ..
.. .. .. .. (facing north)
.. .. FL FR
.. .. RL RR

1) FRF:
.. .. .. ..
.. .. .. FR (facing north)
.. .. FL ..
.. .. RL RR

2) FRP:
.. RL FL ..
.. RR .. FR (facing east)
.. .. .. ..
.. .. .. ..

3) RRF:
.. RL FL ..
.. .. RR FR (facing east)
.. .. .. ..
.. .. .. ..

4) RLP:
.. RL .. ..
RR FL .. .. (facing south)
FR .. .. ..
.. .. .. ..

5) FRF:
.. RL .. ..
RR FL .. .. (facing south)
.. .. .. ..
FR .. .. ..
```

You can observe that the moves shift by rotations. In other words, forward becomes right, right becomes back, back becomes left, left becomes forward in one rotation. For instance, Bessie moves forward (MOVE=0) in steps 1,3 and 5. In the first one, the direction is north (DIR=0). In steps 3 and 5, the directions are east (DIR=1) and south (DIR=2). Forward move (MOVE=0) means to move right (MOVE=1) and back (MOVE=2) when facing east (DIR=1) and south (DIR=2) respectively. As a summary, we can calculate the absolute direction of the current move by MOVE = (MOVE + DIR) % 4.

Now, the issue is to do the rotation. We need to calculate the new positions for the feet. Consider the following rotation:

```1) FRF:
-2 -1  0  1
-2 .. .. .. ..
-1 .. .. .. FR
0 .. .. FL ..
1 .. .. RL RR

2) FRP:
-2 -1  0  1
-2 .. RL FL ..
-1 .. RR .. FR (facing east)
0 .. .. .. ..
1 .. .. .. ..
```

New coordinate of a foot (y1,x1) is (y0+x1-x0,x0+y0-y1) where (y0,x0) is the position of the pivot foot. In the example above, the rotation is as follows:

```	initial position	after rotation
------------		------------
FL	(0,0)			(-1+0-1,1-1-0)=(-2,0)
FR	(-1,1)			(-1,1)
RL	(1,0)			(-1+0-1,1-1-1)=(-2,-1)
RR	(1,1)			(-1+1-1,1-1-1)=(-1,-1)
```

The solution requires O(N) time. The sample code is provided below:

```#include <fstream>
#include <algorithm>

using namespace std;

const int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; 	// (dy,dx)
{0:forward,1:right,2:back,3:left}
struct Point { int y,x; }
foot[4]={{0,0},{0,1},{1,0},{1,1}};	// initial feet positions
int dir;					// {0:north,1:west,2:south,3:east}
int miny,minx,maxy,maxx;			// min - max coordinates of the area

int move(string s)
{
// determine the foot
int f=0;
if (s[0]=='F' && s[1]=='R') f=1;
else if (s[0]=='R')
if (s[1]=='L') f=2;
else f=3;

// clockwise rotation
if (s[2]=='P')
{
for (int i=0; i<4; i++)
{
int ny=foot[f].y+foot[i].x-foot[f].x;
int nx=foot[f].x+foot[f].y-foot[i].y;
foot[i].y=ny,foot[i].x=nx;
}
dir=(dir+1)%4;		// rotate direction clockwise
}
// move
else
{
// get the relative direction
int m=0;
if (s[2]=='R') m=1;
if (s[2]=='B') m=2;
if (s[2]=='L') m=3;
m=(m+dir)%4;		// calculate the absolute direction

foot[f].y+=d[m][0];
foot[f].x+=d[m][1];

// check if Bessie trips
for (int i=0; i<4; i++)
if (f!=i && foot[f].y==foot[i].y && foot[f].x==foot[i].x)
return 0;
}

// update minimum size rectangle
for (int i=0; i<4; i++)
{
if (miny>foot[i].y) miny=foot[i].y;
if (maxy<foot[i].y) maxy=foot[i].y;
if (minx>foot[i].x) minx=foot[i].x;
if (maxx<foot[i].x) maxx=foot[i].x;
}
return 1;
}

int main()
{
ifstream fin("ballet.in");
ofstream fout("ballet.out");

int n,valid=1;
fin >> n;
string inst;
for (int i=0; i<n; i++)
{
fin >> inst;
if (!(valid=move(inst))) break;
}

if (valid)
fout << (maxy-miny+1)*(maxx-minx+1) << endl;
else
fout << -1 << endl;

fin.close();
fout.close();
}
```