There will be at most 1000 test cases. Each case contains a command sequence with no more than 1000 characters.
For each test case, print the case number, followed by minimal/maximal possible x (in this order), then the minimal/maximal possible y.
F?F L?? LFFFRF
Case 1: 1 3 -1 1 Case 2: -1 1 0 2 Case 3: 1 1 3 3
Hint
想法:
代码:这题坑的地方就在于不能够往平面上去想,最开始是dp[x][y][d]表示在坐标(x,y)位置,方向为d,得到的坐标极值。
但肯定超时。。。
所以只能够聪明一点,对字符串做dp了。。
dp[i][j]表示到达第i个字符的命令,此时机器人的方向为j时得到的坐标极值,状态表示出来了,方程就很简单了。。
由于要求Xmin,Xmax,Ymin,Ymax,所以四次DP即可。。
#include<iostream>
#include<cstdio>
#include<cstring>
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
using namespace std;
const int maxn = 1005;
const int inf = 0x3f3f3f3f;
int dp[maxn][4],n;
char str[maxn];
int MAX(int a,int b,int c,int d)
{
return max(a,max(b,max(c,d)));
}
int MIN(int a,int b,int c,int d)
{
return min(a,min(b,min(c,d)));
}
void DP1()
{
for(int i = 0; i < n; i++)
for(int j = 0; j < 4; j++)
dp[i][j] = inf;
if(str[0] == 'F')
dp[0][1] = 1;
else if(str[0] == 'L')
dp[0][0] = 0;
else if(str[0] == 'R')
dp[0][2] = 0;
else
{
dp[0][0] = 0;
dp[0][1] = 1;
dp[0][2] = 0;
}
for(int i = 1; i < n; i++)
for(int j = 0; j < 4; j++) //上一个指令执行后的方向
{
if(str[i] == 'F') //前进
{
if(j == 0) //向上
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else if(j == 1) //向右
dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
else if(j == 2) //向下
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else //向左
dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
}
else if(str[i] == 'L')
{
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
else if(str[i] == 'R')
{
int d = (j + 1) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
else
{
if(j == 0) //向上
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else if(j == 1) //向右
dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
else if(j == 2) //向下
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else //向左
dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
d = (j + 1) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
}
}
void DP2()
{
for(int i = 0; i < n; i++)
for(int j = 0; j < 4; j++)
dp[i][j] = -inf;
if(str[0] == 'F')
dp[0][1] = 1;
else if(str[0] == 'L')
dp[0][0] = 0;
else if(str[0] == 'R')
dp[0][2] = 0;
else
{
dp[0][0] = 0;
dp[0][1] = 1;
dp[0][2] = 0;
}
for(int i = 1; i < n; i++)
for(int j = 0; j < 4; j++) //上一个指令执行后的方向
{
if(str[i] == 'F') //前进
{
if(j == 0) //向上
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else if(j == 1) //向右
dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
else if(j == 2) //向下
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else //向左
dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
}
else if(str[i] == 'L')
{
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
else if(str[i] == 'R')
{
int d = (j + 1) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
else
{
if(j == 0) //向上
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else if(j == 1) //向右
dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
else if(j == 2) //向下
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else //向左
dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
d = (j + 1) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
}
}
void DP3()
{
for(int i = 0; i < n; i++)
for(int j = 0; j < 4; j++)
dp[i][j] = inf;
if(str[0] == 'F')
dp[0][1] = 0;
else if(str[0] == 'L')
dp[0][0] = 0;
else if(str[0] == 'R')
dp[0][2] = 0;
else
{
dp[0][0] = 0;
dp[0][1] = 0;
dp[0][2] = 0;
}
for(int i = 1; i < n; i++)
for(int j = 0; j < 4; j++) //上一个指令执行后的方向
{
if(str[i] == 'F') //前进
{
if(j == 0) //向上
dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
else if(j == 1) //向右
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else if(j == 2) //向下
dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
else //向左
dp[i][j] = min(dp[i][j],dp[i-1][j]);
}
else if(str[i] == 'L')
{
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
else if(str[i] == 'R')
{
int d = (j + 1) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
else
{
if(j == 0) //向上
dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
else if(j == 1) //向右
dp[i][j] = min(dp[i][j],dp[i-1][j]);
else if(j == 2) //向下
dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
else //向左
dp[i][j] = min(dp[i][j],dp[i-1][j]);
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
d = (j + 1) % 4;
dp[i][d] = min(dp[i][d],dp[i-1][j]);
}
}
}
void DP4()
{
for(int i = 0; i < n; i++)
for(int j = 0; j < 4; j++)
dp[i][j] = -inf;
if(str[0] == 'F')
dp[0][1] = 0;
else if(str[0] == 'L')
dp[0][0] = 0;
else if(str[0] == 'R')
dp[0][2] = 0;
else
{
dp[0][0] = 0;
dp[0][1] = 0;
dp[0][2] = 0;
}
for(int i = 1; i < n; i++)
for(int j = 0; j < 4; j++) //上一个指令执行后的方向
{
if(str[i] == 'F') //前进
{
if(j == 0) //向上
dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
else if(j == 1) //向右
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else if(j == 2) //向下
dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
else //向左
dp[i][j] = max(dp[i][j],dp[i-1][j]);
}
else if(str[i] == 'L')
{
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
else if(str[i] == 'R')
{
int d = (j + 1) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
else
{
if(j == 0) //向上
dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
else if(j == 1) //向右
dp[i][j] = max(dp[i][j],dp[i-1][j]);
else if(j == 2) //向下
dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
else //向左
dp[i][j] = max(dp[i][j],dp[i-1][j]);
int d = ((j - 1) % 4 + 4) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
d = (j + 1) % 4;
dp[i][d] = max(dp[i][d],dp[i-1][j]);
}
}
}
int main()
{
int cas = 1;
while(scanf("%s",str)!=EOF)
{
n = strlen(str);
DP1();
printf("Case %d: %d ",cas++,MIN(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
DP2();
printf("%d ",MAX(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
DP3();
printf("%d ",MIN(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
DP4();
printf("%d\n",MAX(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
}
return 0;
}