編輯器操作:輸入字符 (press)、複製 (copy)、刪除。給定 n 個字符串,求輸入所有字符串所需的最少 press 次數。可任意調整輸入順序。
將字符串字典序排序後,相鄰字符串公共前綴最長。輸入順序按排序後順序,每個新字符串只需輸入與前一個字符串不重疊的後綴部分。
#include
#include
#include
using namespace std;
const int MAXN = 105;
struct Word { char s[MAXN]; } w[MAXN];
bool cmp(const Word& a, const Word& b) {
return strcmp(a.s, b.s) < 0;
}
int lcp(const char* a, const char* b) {
int i = 0;
while (a[i] && a[i] == b[i]) i++;
return i;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
int n; scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%s", w[i].s);
sort(w, w+n, cmp);
int ans = strlen(w[0].s);
for (int i = 1; i < n; i++)
ans += strlen(w[i].s) - lcp(w[i-1].s, w[i].s);
printf("%d\n", ans);
for (int i = 0; i < n; i++) printf("%s\n", w[i].s);
}
return 0;
}
| 細節 | 處理 |
|---|---|
| 輸入順序輸出 | 題目要求輸出實際輸入順序,即排序後順序 |
| 複製操作 | 隱含在 LCP 復用中:複製前綴成本為 0 press |
| 刪除操作 | 不需要顯式建模,因只計算 press 次數 |
| 字符串長度 | ≤80,strcmp 直接用 |
Input: 1 3 abc abd xyz 排序: abc, abd, xyz cost = 3 + (3-2) + (3-0) = 7 操作序列: abc (3 press) abd: copy "ab", press 'd' (1 press) xyz: press 'x','y','z' (3 press) 總計 7 press
UVA 10602 是字符串貪心經典題。核心技巧:字典序排序最大化相鄰公共前綴。這一思想廣泛應用於:字典树構建、壓縮算法、版本控制差異計算、DNA 序列比對等領域。代碼簡短但需深刻理解貪心正確性證明。