火车进站问题的求解——华为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运行得分





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