[CF1072D]Codeforce 1072 D. Minimum path

传送门

CF1072D

Description

You are given a matrix of size n × n n×n n×n filled with lowercase English letters. You can change no more than k k k 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 2 n − 1 2n−1 2n1.
Find the lexicographically smallest string that can be associated with a path after changing letters in at most k k k cells of the matrix.
A string a a a is lexicographically smaller than a string b b b, if the first different letter in a a a and b b b is smaller in a a a.
大意就是给你一个 n × n n×n n×n的小写字符方阵,可以更改不超过k位,求一条字典序最小的最短路径。

Input

The first line contains two integers n n n and k k k ( 1 ≤ n ≤ 2000 1≤n≤2000 1n2000, 0 ≤ k ≤ n 2 0≤k≤n^{2} 0kn2) — the size of the matrix and the number of letters you can change.
Each of the next n n n lines contains a string of n n n 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 k k k letters in the matrix.

Example

Input#1

4 2
abcd
bcde
bcad
bcde

Output#1

aaabcde

Input#2

5 3
bwwwz
hrhdh
sepsp
sqfaf
ajbvw

Output#2

aaaepfafw

Input#3

7 6
ypnxnnp
pnxonpm
nxanpou
xnnpmud
nhtdudu
npmuduh
pmutsnz

Output#3

aaaaaaadudsnz

Note

In the first sample test case it is possible to change letters ‘b’ in cells ( 2 , 1 ) (2,1) (2,1) and ( 3 , 1 ) (3,1) (3,1) to ‘a’, then the minimum path contains cells ( 1 , 1 ) (1,1) (1,1), ( 2 , 1 ) (2,1) (2,1), ( 3 , 1 ) (3,1) (3,1), ( 4 , 1 ) (4,1) (4,1), ( 4 , 2 ) (4,2) (4,2), ( 4 , 3 ) (4,3) (4,3), ( 4 , 4 ) (4,4) (4,4). The first coordinate corresponds to the row and the second coordinate corresponds to the column.

Hint

time limit per test: 1.5 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Solution

  • 计算从 ( 1 , 1 ) (1,1) (1,1)到该点经过的最多’a’的个数,对于小于k个的,直接改为’a’
  • 枚举步数和每一步会走到的点,贪心地取即可

Code

//Beginner_df016
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int read(){
	int x=0; bool f=0; char ch=getchar();
	while (ch<'0' || ch>'9'){if (ch=='-') f=1; ch=getchar();}
	while (ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-48; ch=getchar();}
	return (f)?-x:x;
}
const int N=2007;
const int Inf=1e7+7;
int n,k,tot,top,f[N][N];
char a[N][N],ans[N<<1];
bool p[N][N];
int main(){
	n=read(); k=read();
	for (int i=0;i<n;++i) scanf("%s",a[i]);
	if (k>=2*n-1){
		for (int i=1;i<2*n;++i) putchar('a');
		printf("\n");
		return 0;
	}
	for (int i=0;i<n;++i)
	for (int j=0;j<n;++j) f[i][j]=Inf;
	f[0][0]=1;
	if (a[0][0]=='a') f[0][0]--;
	for (int i=0;i<n;++i)
	for (int j=0;j<n;++j){
		if (f[i][j]<=k) a[i][j]='a';
		f[i+1][j]=min(f[i+1][j],f[i][j]+(a[i+1][j]=='a'?0:1));
		f[i][j+1]=min(f[i][j+1],f[i][j]+(a[i][j+1]=='a'?0:1));
	}
	for (int i=0;i<2*n-1;++i){
		char minn='z';
		int t=min(n,i+1);
		for (int x=max(0,i-n+1);x<t;++x){
			int y=i-x;
			if ((x==0 && y==0) || (x>0 && p[x-1][y]) || (y>0 && p[x][y-1]))
				minn=min(minn,a[x][y]);
		}
		for (int x=max(0,i-n+1);x<t;++x){
			int y=i-x;
			if (((x==0 && y==0) || (x>0 && p[x-1][y]) || (y>0 && p[x][y-1])) && a[x][y]==minn)
				p[x][y]=1;
		}
		ans[++tot]=minn;
	}
	for (int i=1;i<=tot;++i) putchar(ans[i]);
	printf("\n");
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值