华为OJ—火车进站(栈,字典排序)

给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号。要求以字典序排序输出火车出站的序列号。其实也就是输出所有可能的出栈序列。

样例输入:

3

1 2 3

样例输出:

1 2 3
1 3 2
2 1 3
2 3 1
3 2 1

解答:

  其实核心就是一个栈,对于第K个数,在第K个数进栈之前,前面的 K-1 个数要么全部出去了,要么都在栈里面,要么部分在栈里面部分出去了。那么可以假想,在第K个数入栈之前,依次从栈里面出去 0个、1个、2个……栈.size()个,然后把第K个入栈,再对于 K+1个同样实施这样的方法——这就是个递归了。

  出去了的保存在一个队列里面,没出站的保存在栈里面,最后一辆车处理完了递归结束并输出。

#include <iostream>
#include <vector>
#include <stack>

using namespace std;

int n;
int *pArr=NULL;

void handle(int index, stack<int> s, vector<int> v,vector<vector<int> >& res)
{
    //对于每一个待处理的数字,先处理栈里面的,再处理这个数字
    for (int i = s.size(); i >=0; i--)
    {
        //栈里面的数字可以出来 [0个, 全部],出来的就放到了vector里面待输出了
        stack<int> sTemp(s);
        vector<int>vTemp(v);

        //从栈里面出 i 个到队列里面去
        for (int j = 1; j <= i; j++)
       {
            int top = sTemp.top();
            sTemp.pop();
            vTemp.push_back(top);
        }

         //再处理这个,把它放到栈顶

         sTemp.push(pArr[index]);

        if (n-1==index)
         {
           //输出结果
            vector<int> vRes;

            for (int i = 0; i < vTemp.size(); i++)
                vRes.push_back(vTemp[i]);

           while (!sTemp.empty())
            {
                int top = sTemp.top();
               sTemp.pop();
                vRes.push_back(top);
            }
            res.push_back(vRes);
        }
         else
        {
            //递归处理
            handle(index+1, sTemp, vTemp,res);
         }
    }
 }

void swap(vector<vector<int> >& d,int low,int high)
{
    int tmp;

    for(int i=0;i<d[low].size();i++)
    {
        tmp=d[low][i];
        d[low][i]=d[high][i];
        d[high][i]=tmp;
    }
}

int compare(vector<int> a1,vector<int>a2)
{
    int size=a1.size();
    for(int i=0;i<size;)
    {
        if(a1[i]==a2[i])
            i++;
        else
        {
            if(a1[i]>a2[i])
                return 1;
            else
                return -1;
        }
    }
}

void fast_sort(vector<vector<int> >& d,int low,int high)
{
    int left=low,right=high;
    if(low>=high)
        return;
    while(left!=right)
    {
        if(compare(d[right],d[low])>0 &&left<right)
            right--;
        if(compare(d[left],d[low])<0 && left<right)
            left++;
        if(left<right)
            swap(d,left,right);
    }
    swap(d,low,left);

    fast_sort(d,low,left-1);
    fast_sort(d,left+1,high);
}

void dictionary_sort(vector<vector<int> >& d)
{
    if(d.size()<2)
        return;
    else
    {
        int tmp;

        for(int i=0;i<d.size();i++)
        {
            flag=d[i].size();
            tmp=0;

            for(int j=0;j<flag;j++)
            {
                coeff=1;
                for(int k=1;k<flag-j;k++)
                    coeff*=10;
                tmp+=d[i][j]*coeff;
            }
            v_tmp.push_back(tmp);
        }

        fast_sort(d,0,v_tmp.size()-1);

        return;
    }

}

int main(void)
{
    cin >> n;

   pArr=new int[n];
   vector<vector<int> > result;

   for (int i = 0; i < n; i++)
       cin >> pArr[i];

   stack<int> s;
   vector<int> v;
   handle(0, s, v,result);
   dictionary_sort(result);
    for(int i=0;i<result.size();i++)
    {
        for(int j=0;j<n-1;j++)
            cout<<result[i][j]<<" ";
        cout <<result[i][n-1]<<endl;
    }
   delete [] pArr;

}
函数 void dictionary_sort()是对得到的结果按字典序排序。字典序排序的具体方法为快速排序法,由于数据比较小,也可用冒泡排序法。

参考:  华为OJ—火车进站(栈,字典排序)

时间: 2024-08-06 03:41:07

华为OJ—火车进站(栈,字典排序)的相关文章

【华为OJ】【046-成绩排序】

[华为OJ][算法总篇章] [华为OJ][046-成绩排序] [工程下载] 题目描述 查找和排序 题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理. 例示: jack 70 peter 96 Tom 70 smith 67 从高到低 成绩 peter 96 jack 70 Tom 70 smith 67 从低到高 smith 67 Tom 70 jack 70 peter 96 输入描述 输入多行,先输入要排序的人的个数,然后分别输入

全排列——火车进站问题(华为OJ)

今天发现一个非常好用的函数next_permutation(),利用这个函数这以很容易的列出一组数据的所有排列组合. 利用全部排列解决了火车进站问题,下面是题目和源码: 题目:给定一个正整数N代表火车数量,0 #include<vector> #include<stack> #include<string> #include<iostream> #include<algorithm> using namespace std; //////////

【华为OJ】【072-火车进站】

[华为OJ][算法总篇章] [华为OJ][072-火车进站] [工程下载] 题目描述 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车, 每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号 思路: 此处所谓字典序排序的意思是这n辆火车有多少种出站的可能顺序(也就是数据结构中的栈有多少种出栈顺序). 思路为用三个变量分别存储待进站火车,站中火车和已出站火车,其中待进站火车用Queue(队列)存储和站中 火车采用stack(栈)存储,已出站火车采用St

[华为机试练习题]13.火车进站

题目 描述: 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 题目类别: 栈 难度: 高级 运行时间限制: 10Sec 内存限制: 128MByte 阶段: 入职前练习 输入: 有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample. 样例

华为机试题 火车进站

描述:给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列 输入: 有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample. 样例输入: 3 1 2 3 样例输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 思路:先对输入序列进行字

华为OJ:分段排序

题目有点绕,一个是要二分,用三个字符串,存前,中,后三个,前,后部分都降序排序,然后后半部分再反转一下,讲三部分合起来就好了. import java.util.Scanner; public class dividesort { public static void sort(StringBuffer s){ for(int i=0;i<s.length();i++){ for(int j=i;j<s.length();j++){ if(s.charAt(i)>s.charAt(j))

【华为OJ】【024-字符串排序】

[华为OJ][算法总篇章] [华为OJ][024-字符串排序] [工程下载] 题目描述 编写一个程序,将输入字符串中的字符按如下规则排序. 规则1:英文字母从A到Z排列,不区分大小写.如,输入:Type 输出:epTy 规则2:同一个英文字母的大小写同时存在时,按照输入顺序排列.如,输入:BabA 输出:aABb 规则3:非英文字母的其它字符保持原来的位置.如,输入:By?e 输出:Be?y 样例: 输入: A Famous Saying: Much Ado About Nothing(2012

栈:火车进站

题目描述 这里有n列火车将要进站再出站-- 但是,每列火车只有1节---那就是车头-- 描述 有n列火车按1到n的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出. (某生:不就是个栈吗?每次可以让右侧头火车进栈,或者让栈顶火车出站? 老师:闭嘴!) 就像这样: 出站<---    <--进站 |车| |站| |__| 现在请你按<字典序>输出前20种可能的出栈方案. 输入 一个

C++ HOJ 火车进站

[问题描写叙述] 给定一个正整数N代表火车数量.0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号. 要求以字典序排序输出火车出站的序列号. 输入: 有多组測试用例,每一组第一行输入一个正整数N(0<N<10),第二行包含N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每一个编号以空格隔开,每一个输出序列换行.详细见sample. 例子输入: 3 1 2 3 例子输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 [