2022 RoboCom 世界机器人开发者大赛-本科组(国赛)个人题解

发布时间 2023-06-18 14:54:05作者: Echo_J

RC-u4 变牛的最快方法

思路

最短编辑距离+记录路径板子题,不懂最短编辑距离的可以看看网上的博客。不懂为什么官方题解用的bfs写法,然后网上所有的题解就是bfs了。我这里就是双重for循环实现,参考下写法即可。

代码

点击查看代码
#include<bits/stdc++.h>
#define x first
#define y second
#define PII pair<int,int>
using namespace std;
const int N = 1e3+9;
int a[N],b[N],n,m,dp[N][N],op[N][N];
PII pre[N][N];
int main() {
	int xx;
	while(cin>>xx&&xx!=-1) a[++n]=xx;
	while(cin>>xx&&xx!=-1) b[++m]=xx;
	memset(op,-1,sizeof op);
	//初始化很重要 
	for(int i=0; i<=n; ++i) dp[i][0]=i,op[i][0]=0,pre[i][0]={i-1,0};//删除 
	for(int i=0; i<=m; ++i) dp[0][i]=i,op[0][i]=3,pre[0][i]={0,i-1};//插入 
	for(int i=1; i<=n; ++i) {
		for(int j=1; j<=m; ++j) {
			int c=(a[i]!=b[j]);
			int add = dp[i][j-1]+1;//在a[i]前面添加b[j]
			int del = dp[i-1][j]+1;//删除a[i]
			int rce=dp[i-1][j-1]+c;//替换a[i]为b[j]
			dp[i][j]=min(add,min(del,rce));
			if(dp[i][j]==rce) {
				op[i][j]=1;//记录操作 
				pre[i][j]={i-1,j-1};//记录从哪里转移来的,下面同理 
				if(a[i]==b[j]) op[i][j]=2;
			}
			else if(dp[i][j]==add) op[i][j]=3,pre[i][j]={i,j-1};
			else  op[i][j]=0,pre[i][j]={i-1,j};
		}
	}
	cout<<dp[n][m]<<endl;
	//从右下角(n,m)根据pre数组,往回找路径 
	PII t = {n,m};
	vector<int> ans;
	while(t.x||t.y){
		ans.push_back({op[t.x][t.y]});
		t=pre[t.x][t.y]; 
	}
	reverse(ans.begin(), ans.end());
	for(auto &it : ans) cout<<it;
	return 0;
}
/*
in: 
1 -1
3 2 1 -1
out:
2
332 
*/