火車進站問題的求解——華爲OJ高級難度題目

一、問題描述

        關於火車進站問題的描述是這樣的:N代表火車數量,0<N<10,接下來輸入火車入站的序列,一共N輛火車,每輛火車以數字1-9編號。要求以字典序排序輸出火車出站的序列號。火車進站的序列是固定的,爲輸入時的序列,火車站有一箇中轉站是棧結構(先進後出),每一輛火車進入火車站,可以直接開出火車站,也可以先進入中轉站,後面可以再任何時候,選擇是否從中轉站出來,但應符合出棧的規則。

       一個實例描述:輸入數字3代表總共有3輛車,然後輸入三個數字,代表入站的火車編號:1 2 3

                                   輸出所有的出站序列,並按字典排序從小到大排序:1 2 3   1 3 2    2 1 3   2 3 1  3 2 1

二、問題分析

         最開始看到這個題目想到做出該題目的第一步,是要能夠寫出一個程序,可以在給定入站序列的情況下,輸出所有的出站序列,其實該問題的核心就是解決任意序列入棧,有多少種出棧序列。然後題目要求按字典排序,這裏就可以將所有的出站序列都找到後,然後執行一次排序算法就可以。在解決字典排序算法時候,本來想採用快速排序來提高算法的效率,後來覺得輸入的火車數量不大,就採用了一個簡單的插入排序來寫的,提交到OJ平臺上,算法得到了滿分。   

        另外我從節省內存空間角度還想到了一種思維,是否能夠在找到所有序列的時候就按照字典排序從小到大找到所有序列,仔細的想了想,覺得這種方式將多種功能放在一起實現,就顯得有些複雜,各部分功能不獨立,因此後來實現整個問題的解決時,還是採用了上面的方法。即找到的一個出站序列,先保存到數組中,然後再對數組中的數據進行一次排序,最後輸出數組的內容即可。


三、程序源代碼與代碼功能分析

       對一些變量我採用了全局變量來記錄,這樣方便寫程序時候的傳值問題。我採用的是整形數據類型來存儲數據,也可以採用char類型。因此在最後排序的時候,我自己寫了一個compare()函數來對比兩個整形數組的字典序大小,功能類似庫函數的字符串比較函數strcmp()。另外,這個函數int stackinout(int *s, int snum, int *o, int onum, int i)就是實現找到所有的出站序列,採用的是遞歸的方式來實現,基本思想是:每次都有一列火車要進入中轉站,只要中轉站裏面火車數量不爲0,中轉站最外面的火車就可以有兩種選擇,留在中轉站中或者出站,如果中轉站沒有火車了,且沒有火車等待入站,所有在中轉站的火車就依次出站。然後採用遞歸的方式來進行,直到所有的火車都出站即找到一個出站序列。


#include "stdio.h"
int a[10],num=0,r[10000][9],count=0;
int stackinout(int *s, int snum, int *o, int onum, int i);
int compare(int *s,int *d,int num);
int sort(int num);
void main()
{
int i=0,j=0,s[9],o[9];
scanf("%d",&num);
for (;i<num-1;++i)
{
scanf("%d ",&a[i]);
}
scanf("%d",&a[i]);
stackinout(s,0,o,0,0);
sort(num);
for (i=0;i<count;++i)
{
for (j=0;j<num-1;++j)
{
printf("%d ",r[i][j]);
}
printf("%d\n",r[i][j]);
}
}
int stackinout(int *s, int snum, int *o, int onum, int i)
{
int k=0,t[10],t2[10],tnum=0;
if (onum==num)
{
for (k=0;k<num;k++)
{
r[count][k]=o[k];
}
count++;
return 0;
}


if (snum==0)
{
if (i<num)
{
s[snum++]=a[i++];
   stackinout(&(*s),snum,&(*o),onum,i);
}
}
else
{
if (i<num)
{
for (k=0;k<num;k++)
{
t[k]=s[k];
t2[k]=o[k];
}
s[snum++]=a[i++];
   stackinout(&(*s),snum,&(*o),onum,i);
snum--;
i--;
for (k=0;k<num;k++)
{
s[k]=t[k];
o[k]=t2[k];
}
            o[onum++]=s[--snum];
stackinout(&(*s),snum,&(*o),onum,i);
}
else
{
o[onum++]=s[--snum];
   stackinout(&(*s),snum,&(*o),onum,i);
}
}


return 0;
}
int compare(int *s,int *d,int num)
{
int i=0;
for (i=0;i<num;++i)
{
if (s[i]<d[i])
{
return -1;
}
else if(s[i]>d[i])
{
return 1;
}
}
printf("hello\n");
return 0;
}
int sort(num)
{
int i=0,j=0,b[9],k=0;
for (i=1;i<count;++i)
{
for (j=i;j>0;--j)
{
if(compare(r[j],r[j-1],num)==-1)
{
for (k=0;k<num;++k)
{
b[k]=r[j][k];
r[j][k]=r[j-1][k];
r[j-1][k]=b[k];
}
}
}
}
return 0;
} 

四、程序運行結果



                                                                                                        圖1 程序測試運行結果1


                                                                 圖2 程序測試運行結果2



                                                                                                                        圖3 程序測試OJ運行得分





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章