cf1072D. Minimum path(BFS)
阿新 • • 發佈:2018-10-31
題意
給出一個\(n \times n\)的矩陣,允許修改\(k\)次,求一條從\((1, 1)\)到\((n, n)\)的路徑。要求字典序最小
Sol
很顯然的一個思路是對於每個點,預處理出從\((1, 1)\)到該點最多能經過多少個\(1\)
然後到這裡我就不會做了。。
接下來應該還是比較套路的吧,就是類似於BFS一樣,可以列舉步數,然後再列舉向下走了幾次,有點分層圖的感覺。
/* */ #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL long long #define rg register #define pt(x) printf("%d ", x); #define Fin(x) {freopen(#x".in","r",stdin);} #define Fout(x) {freopen(#x".out","w",stdout);} using namespace std; const int MAXN = 2001, INF = 1e9 + 10, mod = 1e9 + 7, B = 1; const double eps = 1e-9; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, K, vis[MAXN][MAXN], f[MAXN][MAXN]; char s[MAXN][MAXN]; int main() { N = read(); K = read(); for(int i = 1; i <= N; i++) scanf("%s", s[i] + 1); for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) { f[i][j] = max(f[i - 1][j], f[i][j - 1]); if(s[i][j] == 'a') f[i][j]++; if(i + j - 1 - f[i][j] <= K) s[i][j] = 'a'; } } putchar(s[1][1]); vis[1][1] = 1; for(int i = 3; i <= N << 1; i++) {//all step char now = 'z' + 1; for(int j = 1; j < i; j++) { // num of down if(j > N || (i - j > N)) continue; if(!vis[j - 1][i - j] && !vis[j][i - j - 1]) continue; now = min(now, s[j][i - j]); } putchar(now); for(int j = 1; j < i; j++) { // num of down if(j > N || (i - j > N)) continue; if(!vis[j - 1][i - j] && !vis[j][i - j - 1]) continue; if(s[j][i - j] == now) vis[j][i - j] = 1; } } return 0; } /* */