1. 程式人生 > >Codeforces Round #517 (Div. 2), problem (D) Minimum path 貪心

Codeforces Round #517 (Div. 2), problem (D) Minimum path 貪心

本題運用貪心演算法,需要按照字典序輸出路徑,路徑包含2n-1個字元,只需要按正序求出當前情況下的最優解即可。需要注意的是當最優解相同的時候需要保留剩餘更改次數更大的那個路徑。

在求解本題的過程中由於構思的偏差出現了Runtime error、Memory limit exceeded等錯誤。在這裡記錄一下錯誤原因。

Runtime error的錯誤原因主要有陣列訪問越界(我就是)、發生除零錯誤、大陣列定義在函式內導致程式棧區耗盡、指標訪問錯誤的記憶體區域。

Memory limit exceeded是之前用vector導致的。vector不適合在程式中多次刪除,因為除非用swap函式,否則不會釋放記憶體。(雖然我用來swap好像還是Memory limit exceeded不知道為啥了)

ac程式碼:

#include <bits/stdc++.h>
#define FOR(I,A,B) for(int I = (A); I < (B); I++)
#define FORE(I,A,B) for(int I = (A); I <= (B); I++)
#define PRII pair<int,int> 
#define LL long long 
#define INF 1000000001
using namespace std;
int n,k;
char l[2005][2005];
char jl[4005];
int rm[2005][2005];
int main
() { cin>>n>>k; FOR(i,0,n){ string s; cin>>s; FOR(j,0,n) l[i][j]=s[j]; } FOR(i,0,n*2-1) jl[i]='z'; memset(rm,-1,sizeof(rm)); rm[0][0]=k; FOR(i,0,n*2-1){ char mn='z'; FORE(j,0,i){ if(j>=n||i-j>=n) continue; if(rm[j][i-j]>=0){ char c=l[j][i-j]; if(c!=
'a'&&rm[j][i-j]>0) c='a'; mn=mn<c?mn:c; } } jl[i]=mn; FORE(j,0,i){ if(j>=n||i-j>=n) continue; if(rm[j][i-j]>=0){ char c=l[j][i-j]; if(c!='a'&&rm[j][i-j]>0){ c='a'; rm[j][i-j]--; } if(c==mn){ if(j<n-1) rm[j+1][i-j]=rm[j+1][i-j]>rm[j][i-j]?rm[j+1][i-j]:rm[j][i-j]; if(i-j<n-1) rm[j][i-j+1]=rm[j][i-j+1]>rm[j][i-j]?rm[j][i-j+1]:rm[j][i-j]; } } } } FOR(i,0,n*2-1) printf("%c",jl[i]); return 0; }