Codeforces - Minimum path

题目链接:Codeforces - Minimum path


最小字典序显然可以贪心。

我们首先找到使用k次机会,的最大 x+y 的位置,很明显的贪心。现在可能有很多点,要怎么走呢?

我们判断当前所有点的出点,然后存到vector里面,按照字典序排序。因为贪心法则,只有等于第一个字符的才会走,而且一个点只会被更新一次。

所以暴力走然后sort即可。

AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e3+10;
int n,k,sum[N][N],mx,vis[N][N];
char g[N][N];	pair<int,int> pre[N][N];
vector<pair<int,int> > v;
struct node{int x,y,p;};	vector<node> q;
int cmp(node a,node b){return a.p<b.p;}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)	scanf("%s",g[i]+1);
	if(k&&g[1][1]!='a')	k--,g[1][1]='a';
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)	
			sum[i][j]=max(sum[i-1][j],sum[i][j-1])+(g[i][j]=='a');
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)	if(i+j-1<=sum[i][j]+k&&i+j>=mx){
			if(i+j>mx)	v.clear(),v.push_back({i,j}),mx=i+j;
			else	v.push_back({i,j});	
		}
	}
	if(v.size()==0)	v.push_back({1,1}),cout<<g[1][1];
	for(int i=0;i<v.size();i++){
		int x=v[i].first,y=v[i].second;
		if(x+1<=n&&!vis[x+1][y])	
			vis[x+1][y]=1,pre[x+1][y]={x,y},q.push_back({x+1,y,(int)g[x+1][y]});
		if(y+1<=n&&!vis[x][y+1])
			vis[x][y+1]=1,pre[x][y+1]={x,y},q.push_back({x,y+1,(int)g[x][y+1]});
	}
	while(q.size()){
		sort(q.begin(),q.end(),cmp);
		int x=q[0].x,y=q[0].y;	vector<node> t;
		if(x+1<=n&&!vis[x+1][y])	
			vis[x+1][y]=1,pre[x+1][y]={x,y},t.push_back({x+1,y,(int)g[x+1][y]});
		if(y+1<=n&&!vis[x][y+1])
			vis[x][y+1]=1,pre[x][y+1]={x,y},t.push_back({x,y+1,(int)g[x][y+1]});
		for(int i=1;i<q.size();i++){
			if(q[i].p>q[i-1].p)	break;
			x=q[i].x,y=q[i].y;
			if(x+1<=n&&!vis[x+1][y])	
				vis[x+1][y]=1,pre[x+1][y]={x,y},t.push_back({x+1,y,(int)g[x+1][y]});
			if(y+1<=n&&!vis[x][y+1])
				vis[x][y+1]=1,pre[x][y+1]={x,y},t.push_back({x,y+1,(int)g[x][y+1]});
		}
		q.clear();
		for(int i=0;i<t.size();i++)	q.push_back(t[i]);
		t.clear();
	}
	for(int i=1;i<mx;i++)	putchar('a');
	stack<char> res;	int x=n,y=n;
	while(x!=0){
		int tx=x,ty=y;
		res.push(g[x][y]);	x=pre[tx][ty].first,y=pre[tx][ty].second;
	}
	res.pop();
	while(res.size())	cout<<res.top(),res.pop();	
	return 0;
}
发布了477 篇原创文章 · 获赞 241 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104095377
今日推荐