首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

UVA 10152 ShellSort:烏龜疊羅漢最小移動序列構造

     編輯:關於C語言

題目大意

給定初始烏龜堆疊順序(從頂到期)和目標順序。每次操作:選一隻烏龜爬到頂部。求最短操作序列將初始變為目標。

核心洞察

從目標順序自底向上檢查:

  1. 目標底部的烏龜必須最後不動(或最早就位)
  2. 在初始序列中從後向前掃描,匹配目標從後向前的烏龜
  3. 能匹配上的保持不動,無法匹配的必須移動到頂部
  4. 移動順序:按目標順序從前向後輸出需移動的烏龜

算法演示

初始: Yertle, Duke, Lancelot (頂→底)
目標: Duke, Yertle, Lancelot

目標逆序: Lancelot, Yertle, Duke
初始逆序: Lancelot, Duke, Yertle

匹配:
Lancelot ✓ (指針後移)
Yertle   ✗ (初始下一個是 Duke)
Duke     ✗

未匹配: Yertle, Duke → 按目標順序輸出: Duke, Yertle

完整 C++ 代碼


#include 
#include 
#include 
#include 
using namespace std;

int main() {
    int T, n;
    string s;
    cin >> T;
    while (T--) {
        cin >> n; getchar();  // 吸收換行
        vector init(n), target(n);
        for (int i = 0; i < n; i++) getline(cin, init[i]);
        for (int i = 0; i < n; i++) getline(cin, target[i]);
        
        int j = n - 1;
        for (int i = n - 1; i >= 0; i--) {
            if (target[j] == init[i]) j--;
        }
        while (j >= 0) {
            cout << target[j--] << '\n';
        }
        cout << '\n';
    }
    return 0;
}

正確性證明

  • 不動點最大化:從底部開始貪心匹配,保留最長公共後綴子序列
  • 移動必要性:未匹配的烏龜在初始中位置靠前,阻礙了目標順序,必須移到頂部
  • 移動充分性:按目標順序移動未匹配者,每次操作將該烏龜置頂,最終形成目標序列
  • 最少步數:保留了最長的不需移動後綴,移動數 = n - 後綴長度,最優

複雜度分析

指標複雜度
時間O(n) 單次掃描
空間O(n) 存儲字符串
字符串比較O(L) L≤80,可視為常數

關鍵細節

  1. 輸入含空格,必須用 getline 讀整行
  2. cin >> n 後需 getchar() 吸收換行
  3. 測試用例間輸出空行
  4. 烏龜名字唯一,可直接字符串比較

樣例驗證

Input:
2
3
Yertle
Duke of Earl
Sir Lancelot
Duke of Earl
Yertle
Sir Lancelot
9
Yertle
Duke of Earl
Sir Lancelot
Elizabeth Windsor
Michael Eisner
Richard M. Nixon
Mr. Rogers
Ford Perfect
Mack
Yertle
Richard M. Nixon
Sir Lancelot
Duke of Earl
Elizabeth Windsor
Michael Eisner
Mr. Rogers
Ford Perfect
Mack

Output:
Duke of Earl
Sir Lancelot

Richard M. Nixon
Yertle

總結

看似複雜的排序問題,實則是最長公共後綴子序列的變體。逆向思維(從目標底部看)+ 貪心匹配 即得最優解。代碼極短,核心邏輯僅 5 行,是算法競賽中「洞察力 > 代碼量」的經典案例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved