D. Minimum path
time limit per test1.5 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a matrix of size n×nn×n filled with lowercase English letters. You can change no more than kk letters in this matrix.
Consider all paths from the upper left corner to the lower right corner that move from a cell to its neighboring cell to the right or down. Each path is associated with the string that is formed by all the letters in the cells the path visits. Thus, the length of each string is 2n−12n−1.
Find the lexicographically smallest string that can be associated with a path after changing letters in at most kk cells of the matrix.
A string aa is lexicographically smaller than a string bb, if the first different letter in aa and bb is smaller in aa.
Input
The first line contains two integers nn and kk (1≤n≤20001≤n≤2000, 0≤k≤n20≤k≤n2) — the size of the matrix and the number of letters you can change.
Each of the next nn lines contains a string of nn lowercase English letters denoting one row of the matrix.
Output
Output the lexicographically smallest string that can be associated with some valid path after changing no more than kk letters in the matrix.
Examples
inputCopy
4 2
abcd
bcde
bcad
bcde
outputCopy
aaabcde
inputCopy
5 3
bwwwz
hrhdh
sepsp
sqfaf
ajbvw
outputCopy
aaaepfafw
inputCopy
7 6
ypnxnnp
pnxonpm
nxanpou
xnnpmud
nhtdudu
npmuduh
pmutsnz
outputCopy
aaaaaaadudsnz
Note
In the first sample test case it is possible to change letters ‘b’ in cells (2,1)(2,1) and (3,1)(3,1) to ‘a’, then the minimum path contains cells (1,1),(2,1),(3,1),(4,1),(4,2),(4,3),(4,4)(1,1),(2,1),(3,1),(4,1),(4,2),(4,3),(4,4). The first coordinate corresponds to the row and the second coordinate corresponds to the column.
题意:给你一张图,给你一个k值可以将任何k个字母改变,求左上到右下字典序最小的答案
思路:首先用dp[i][j]记录下走到该点全部为a的最小变化值,然后将能变成a的全部变为a
然后就用滚动的优先队列bfs 开优先队列的目的是方便直接找出所有的最小字母加入队列,然后再将每一步能向下向右走的字母加入优先队列直到走到右下角,这里要记录一下加入过队列的字母下标,不然会严重超时!!!
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
#define fi first
#define se second
#define FOR(a) for(int i=0;i<a;i++)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" !!! "<<b<<endl;
#define show3(a,b,c) cout<<a<<" !!! "<<b<<" !!! "<<c<<endl;
#define show4(a,b,c,d) cout<<a<<" !!! "<<b<<" !!! "<<c<<" !!! "<<d<<endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 0x3f3f3f3f;
const int N = 2005;
const ll mod = 998244353;
int n, m, t, x, y, k, sum, cnt, aans;
int r, c, a[N], dex[N], b[N],num[N];
char ans[5000];
int dp[N][N];
int vis[N][N], er[N];
char v[N][N];
struct node
{
char s;
int x,y;
bool operator < (const node& t) const{
return s>t.s;
}
};
priority_queue<node> q;
priority_queue<node> tq;
bool ok(int x,int y)
{
if(x>=0&&y<n&&y>=0&&x<n) return 1;
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%s",v[i]);
if(k>=2*n-1)
{
for(int i=1;i<2*n;i++)
{
printf("a");
}
return 0;
}
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
dp[i][j]=inf;
dp[0][0]=(v[0][0]!='a');
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(dp[i][j]<=k) v[i][j]='a';
dp[i+1][j]=min(dp[i+1][j],dp[i][j]+(v[i+1][j]!='a'));
dp[i][j+1]=min(dp[i][j+1],dp[i][j]+(v[i][j+1]!='a'));
}
}
//for(int i=0;i<=n;i++) cout<<v[i]<<endl;
q.push(node{v[0][0],0,0});
while(q.size())
{
char mi;
int flag=0;
while(q.size())
{
node now=q.top();
q.pop();
if(!flag) mi=now.s,flag=1;
if(now.s==mi)
{
tq.push(now);
//show3(now.s,now.x,now.y)
}
}
//cout<<mi<<endl;
//cout<<tq.size()<<endl;
ans[++cnt]=mi;
while(tq.size())
{
node now=tq.top();
tq.pop();
int x=now.x;
int y=now.y;
if(ok(x+1,y)&&!vis[x+1][y])
{
vis[x+1][y]=1;
q.push(node{v[x+1][y],x+1,y});
//show3(now.s,now.x,now.y)
}
if(ok(x,y+1)&&!vis[x][y+1])
{
vis[x][y+1]=1;
q.push(node{v[x][y+1],x,y+1});
//show3(now.s,now.x,now.y)
}
}
}
for(int i=1;i<=cnt;i++) printf("%c",ans[i]);
}