UVA 10152-ShellSort(映射+栈)

题意: 给出一堆乌龟名字,乌龟能从本身位置爬到顶端。 要求求出从原本的顺序到目标顺序的最小操作。输出每次操作移到顶端的乌龟的名字。

解析:名字用映射对应编号,把目标状态的乌龟从上到下的编号按1到N编好,从最底端开始扫初始状态的元素,如果与右边栈底指针指的元素编号相等,则两方的指针都加1,否则把初始状态的那个元素抽出来,而另一方的指针不变。最后把抽出来的元素按从大到小的顺序排一遍,因为编号大的先被放到顶端,后来就会被小的覆盖。输出即可。

代码如下:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
map<string,int> ma;
string org[205],target[205];
int le_id[205],ri_id[205];       //分别表示初始状态和目标状态
bool cmp(const int& a,const int& b){ return a>b; }
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int N;
        cin>>N;
        getchar();
        ma.clear();
        for(int i=0;i<N;i++)  getline(cin,org[i]);
        for(int i=0;i<N;i++)
        {
            getline(cin,target[i]);                  // 映射编号
            ma[target[i]]=i;
            ri_id[i]=i;
        }
        for(int i=0;i<N;i++)  le_id[i]=ma[org[i]];   // 初始状态编号
        vector<int> save;
        int walk=N-1;
        for(int tail=N-1;tail>=0;tail--)
        {
            if(le_id[tail]==ri_id[walk])  walk--;    //比较,如果相等
            else  save.push_back(le_id[tail]);       //不相等则抽出来
        }
        sort(save.begin(),save.end(),cmp);           //排序
        for(int i=0;i<save.size();i++)  cout<<target[save[i]]<<endl;  //输出
        cout<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wust-ouyangli/p/4743211.html