最长平台

题目 - 最长平台  
来源D.Gries. The Science of Programming, Springer-Verlag, 1981
描述
已知一个已经从小到大排序的数组,这个数组的一个平台(Plateau)就是连续的一串值相同的元素,并且这一串元素不能再延伸。例如,在1,2,2,3,3,3,4,5,5,6中1,2-2,3-3-3,4,5-5,6都是平台。试编写一个程序,接收一个数组,把这个数组最长的平台找出来。在上面的例子中3-3-3就是最长的平台。



 
关于输入
第一行有一个整数n,为数组元素的个数(1若n=0,表示测试数据结尾。
 
关于输出
输出最长平台的长度。
 
例子输入
10

1 2 2 3 3 3 4 5 5 6
5
1 1 1 2 7
0

例子输出
3

3
提示
这个程序十分简单,但是要编好却不容易,因此在编写程序时应考虑以下几点:
(1)使用的变量越少越好。
(2)能否只把每一个数组的元素都只查一次就得到结果?
(3)程序的语句越少越好。
(4)程序运行所用的时间也要越少越好。
当然,同时做到上述几点是不现实的。但我们可以在其中寻求一种平衡。
一个好的程序就是以上几个要素平衡的结果。

例如这个问题,一般的编程思路是这样的:

// 程序名称:最长的平台
// 作者:陈志杰

#include
< stdio.h >

#define  MAX 20

int  main(){
    
int  n,i;
    
int  nList[MAX], // 存放题中的数组
        nBegin, // 标记相同元素的开始位置
        nMax; // 最大平台长度
    scanf( " %d " , & n);
    
while  (n  !=   0 ){
        
for (i  =   0 ; i  <  n; i ++ ){
            scanf(
" %d " , & nList[i]);
        }
// End for
        nMax  =   1 ; // 初始化(想想为什么不使其为0 ?)
         for (i  =   0 ; i  <  n - 1 ; i ++ ){
            
if (nList[i]  ==  nList[i + 1 ]){ // 监测到两个相同的
                nBegin  =  i;
                i
++ ;
                
for (;nList[nBegin]  ==  nList[i]; i ++ ); // 一个语句为空的循环,
                                                     
// 用于将i移向第一个不相同的元素处。

                
if  (nMax  <  i  -  nBegin) nMax  =  i  -  nBegin;
                i
-- ; // 因为此时i已经指向下一个平台,
                    
// 但是FOR最后还有一个i++。

            }
// End if
        } // End for
        printf( " %d " ,nMax);
        scanf(
" %d " , & n);
    }
// End while
     return   0 ;
}
// End Program


大家用这个常规思路编的话,如果注释到位(虽不用像我写的那么多,但要把思路注释清楚),习惯良好,基本就能得到8分以上。

在向大家推荐一种更好的思路:

// 程序名称:最长平台(2)
// 作者:陈志杰
#include < stdio.h >

#define  MAX 20

int  main(){
    
int  n,i;
    
int  nLength, // 记录平台长度(这句注释是给分点)
        nList[MAX]; // 记录数组(这句注释是给分点)
    scanf( " %d " , & n);
    
while ( n  !=   0 ){
        nLength 
=   1 ; // 初始化长度为1(这句注释是给分点)
         for  (i  =   0 ; i  <  n; i ++ )
            scanf(
" %d " , & nList[i]);
        
        
for  (i  =   1 ; i  <  n; i ++ ){
            
if  (nList[i]  ==  nList[i  -  nLength])
                nLength
++ ; // 因为是按顺序排列的,
                          
// 所以若想隔nLength - 1个元素仍然相等的话
                          
// 两者中间的元素必相等,
                          
// 而且这个平台的长度一定比nLength 中储存的长
                          
// 所以nLength ++
                          
// (这段注释是给分点)
        }
        printf(
" %d " ,nLength);
        scanf(
" %d " , & n);    
    }
    
return   0 ;
}



能写出这种思路的,而且注释规范的话,得高分简直是没有问题的~~

(注:其实这段程序不是我写的,是美国一个编程大师的思路~~ 我也想不出来~~ 呵呵)

以上是官话,以下是个人观点:

上面的程序中第一个是我编的,第二个的主要算法部分是迄今为止关于这个问题最短的代码,单从简洁程度来讲,后者肯定比较高级,但是经过提交会发现我的思路用时较短,我想是因为我的思路数组元素的平均读取次数比第二个少,看来鱼和熊掌确实不可兼得哈~~

所以我觉得,大家提交的程序时不必迷信权威,只要在代码量、用时和内存使用量上有一点比较突出(只要其余二者只要不是太差)即可得高分。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值