最长平台

来源:互联网 发布:为知笔记下载 编辑:程序博客网 时间:2024/06/11 18:27
题目 - 最长平台   来源 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;
}



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

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

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

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

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