csu 1510 Happy Robot(字符串DP,记忆化搜索)

Happy RobotTime Limit: 1 Sec  Memory Limit: 128 MB
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 2
Case 3: 1 1 3 3

题意:给一个字符串,包含有四种字符,F表示向前走,L表示在当前位置向左转,R表示在当前位置向右转,?表示执行上面三种任意一种都可以

机器人从(0,0)开始,输出x,y的最小值和最大值

思路:用记忆化搜索从后往前搜索,搜过的位置可以直接返回。DP里要保存在当前这个位置朝向某个方向极值

队友还提供了一种字符串DP的思路,其实也差不多。

关键在于此题不能在二维平面考虑,要在字符串上考虑才可以。

这里给出两个代码,记忆化搜索的方向是上下左右,字符串DP的方向是上右下左

代码1:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define N 1050
#define INF 99999999
struct Node
{
    int minx,maxx,miny,maxy;
} dp[N][4];
char a[N];
int vis[N][4];
int len;
int Min(int b,int c,int d)
{
    if(b>c) b=c;
    return b<d?b:d;
}
int Max(int b,int c,int d)
{
    if(b<c) b=c;
    return b>d?b:d;
}
Node dfs(int k,int f)
{
    if(vis[k][f]) return dp[k][f];
    vis[k][f]=1;
    dp[k][f].minx=dp[k][f].maxx=dp[k][f].miny=dp[k][f].maxy=0;
    if(k==len-1)
    {
        if(a[k]=='F')
        {
            if(f==0) dp[k][f].maxy=1,dp[k][f].miny=1;
            else if(f==1) dp[k][f].maxy=-1,dp[k][f].miny=-1;
            else if(f==2) dp[k][f].minx=-1,dp[k][f].maxx=-1;
            else dp[k][f].minx=1,dp[k][f].maxx=1;
        }
        else if(a[k]=='?')
        {
            if(f==0) dp[k][f].maxy=1;
            else if(f==1) dp[k][f].miny=-1;
            else if(f==2) dp[k][f].minx=-1;
            else dp[k][f].maxx=1;
        }
    }
    else
    {
        if(a[k]=='L')
        {
            if(f==0) dp[k][f]=dfs(k+1,2);
            else if(f==1) dp[k][f]=dfs(k+1,3);
            else if(f==2) dp[k][f]=dfs(k+1,1);
            else dp[k][f]=dfs(k+1,0);
        }
        else if(a[k]=='R')
        {
            if(f==0) dp[k][f]=dfs(k+1,3);
            else if(f==1) dp[k][f]=dfs(k+1,2);
            else if(f==2) dp[k][f]=dfs(k+1,0);
            else dp[k][f]=dfs(k+1,1);
        }
        else if(a[k]=='F')
        {
            if(f==0)
            {
                dp[k][f]=dfs(k+1,0);
                dp[k][f].maxy++;
                dp[k][f].miny++;
            }
            else if(f==1)
            {
                dp[k][f]=dfs(k+1,1);
                dp[k][f].miny--;
                dp[k][f].maxy--;
            }
            else if(f==2)
            {
                dp[k][f]=dfs(k+1,2);
                dp[k][f].minx--;
                dp[k][f].maxx--;
            }
            else
            {
                dp[k][f]=dfs(k+1,3);
                dp[k][f].maxx++;
                dp[k][f].minx++;
            }
        }
        else
        {
            Node b,c,d,e;
            if(f==0)
            {
                b=dfs(k+1,0);
                b.maxy++; b.miny++;
                c=dfs(k+1,2);
                d=dfs(k+1,3);
                dp[k][f].minx=Min(b.minx,c.minx,d.minx);
                dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
                dp[k][f].miny=Min(b.miny,c.miny,d.miny);
                dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
            }
            else if(f==1)
            {
                b=dfs(k+1,1);
                b.maxy--;  b.miny--;
                c=dfs(k+1,3);
                d=dfs(k+1,2);
                dp[k][f].minx=Min(b.minx,c.minx,d.minx);
                dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
                dp[k][f].miny=Min(b.miny,c.miny,d.miny);
                dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
            }
            else if(f==2)
            {
                b=dfs(k+1,2);
                b.maxx--; b.minx--;
                c=dfs(k+1,1);
                d=dfs(k+1,0);
                dp[k][f].minx=Min(b.minx,c.minx,d.minx);
                dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
                dp[k][f].miny=Min(b.miny,c.miny,d.miny);
                dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
            }
            else
            {
                b=dfs(k+1,3);
                b.maxx++; b.minx++;
                c=dfs(k+1,0);
                d=dfs(k+1,1);
                dp[k][f].minx=Min(b.minx,c.minx,d.minx);
                dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
                dp[k][f].miny=Min(b.miny,c.miny,d.miny);
                dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
            }
        }
    }
    return dp[k][f];
}
int main()
{
    int cas=1;
    while(~scanf("%s",a))
    {
        len=strlen(a);
        memset(vis,0,sizeof(vis));
        Node ans=dfs(0,3);
        printf("Case %d: %d %d %d %d\n",cas++,ans.minx,ans.maxx,ans.miny,ans.maxy);
    }
    return 0;
}

代码2:

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






### 回答1: 可以使用Python内置函数`bytes()`和`.hex()`来将字符串转换为16进制表示。具体方法如下: ```python str = "Hello World!" hex_str = bytes(str, encoding='utf-8').hex() print(hex_str) ``` 运行结果为: ``` 48656c6c6f20576f726c6421 ``` 其中,`bytes()`函数将字符串转换为字节流,参数`encoding='utf-8'`指定编码格式为UTF-8;`.hex()`函数将字节流转换为16进制表示。 ### 回答2: Python中可以使用`binascii`模块中的`hexlify`函数将字符串转换为16进制表示。 ```python import binascii def str_to_hex(string): hex_str = binascii.hexlify(string.encode()).decode() return hex_str ``` 在这里,我们首先使用`encode`函数将字符串转换为字节流,然后使用`hexlify`函数将字节流转换为16进制表示。最后,我们使用`decode`函数将字节流转换回字符串,并将结果返回。 下面是一个例子: ```python message = "Hello, World!" hex_message = str_to_hex(message) print(hex_message) # 输出: 48656c6c6f2c20576f726c64214 ``` 在这个例子中,我们将字符串"Hello, World!"转换为16进制表示,并输出结果"48656c6c6f2c20576f726c64214"。 ### 回答3: 在Python中,可以通过使用内置的hex函数将字符串转换为十六进制。 hex函数将每个字符转换为其对应的十六进制表示,然后将其连接成一个字符串。下面是一个示例: ```python string = "Hello, World!" # 原始字符串 hex_string = ''.join([hex(ord(c))[2:] for c in string]) # 将每个字符转换为十六进制,并连接成一个字符串 print(hex_string) # 输出结果为 "48656c6c6f2c20576f726c6421" ``` 在上面的代码中,首先定义了一个字符串变量`string`,其值为"Hello, World!"。然后,通过列表推导式和`hex`函数,将每个字符转换为其十六进制表示。`ord`函数用于获取字符的ASCII码,`hex`函数将ASCII码转换为十六进制字符串。最后,使用`''.join()`函数将每个字符的十六进制表示连接成一个字符串。最终的结果为"48656c6c6f2c20576f726c6421"。 需要注意的是,`hex`函数返回的十六进制字符串以"0x"开头,而我们只需要字符之间的十六进制表示。因此,我们使用切片操作[2:]来去除开头的"0x"。 使用上述方法,你可以将任意字符串转换为十六进制表示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值