Submit: 182 Solved: 85
[ Submit][ Status][ Web Board]
Description
Input
There will be at most 1000 test cases. Each case contains a command sequence with no more than 1000 characters.
Output
For each test case, print the case number, followed by minimal/maximal possible x (in this order), then the minimal/maximal possible y.
Sample Input
F?F
L??
LFFFRF
Sample Output
Case 1: 1 3 -1 1 Case 2: -1 1 0 2Case 3: 1 1 3 3
解题思路:
这题坑的地方就在于不能够往平面上去想,最开始是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; }