现在的位置: 首页 > 综合 > 正文

"有道难题2009"复赛题目

2013年07月13日 ⁄ 综合 ⁄ 共 2097字 ⁄ 字号 评论关闭
突然发现,有道难题也有编程比赛,先看了一下去年的题目,自己写了一个方法,再与官方给出的方法相比较,下面我对我的方法和官方方法作一下比较,找出不足,进步进步"有道难题2009"复赛题目。首先列出题目:
Problem Statement:

如果一个数字十进制表达时,不存在连续两位数字相等,则称之为“不重复数”。例如,105,1234和12121都是“不重复数”,而11,100和1225不算。给定一个long类型数字A,返回大于A的最小“不重复数”。

Definition:

Class: UnrepeatingNumbers
Method: next
Parameters: long
Returns: long
Method signature: long next(long A)
(be sure your method is public)
 

Constraints:

A 取值范围是[0, 10^17],注意是闭区间。

Examples:
0) 54
returns: 56
大于54的最小数字是55,但55不是“不重复数”。下一个数字是56,它满足条件。
1) 10
returns: 12
2) 9 
returns: 10
3) 98
returns: 101
99和100都不是“不重复数”, 101是。
4) 21099 
returns: 21201
 
    这道题目其实不难,可是编程比赛,高手如云,一道简单的题目,厉害的人可以写出效率极高的代码。。这就是竞争啊。。。所以我们平时编程也不能只求完成,还要求效率。效率效率!
    另外,为了比较运行时间,在这里我用了函数clock,以计算程序运行时间。
#include<stdio.h>
#include<time.h>
long next(long n) //我的方法
{
    int i=10;
    long m,a,b;
    n++;
    m=n;
    while(n>9)
    {
        a=n%10;   //低位
        b=n/10%10;//高位
        if(a==b)
        {
            m++;
            n=m;
            i=10;
            continue;
        }
        n/=i;
    }
    return m;
}
long getNext( long A) //官方的方法
{
    A++;
    bool done = true;
    do {
        long d = 1;//每次循环都让d=1
        while (d*10 < A) //因一开始d=1,若一开始A就比10还小,说明比较到达了最高位,则不执行次循环 
           d*=10;        // 直到A比d大
        
        done = true;
        while (d > 1) {  //只要d是大于1的,说明上面已经执行过循环,也就说明未比较到最高位
            long nd = d / 10;
            if ( (A / d) % 10 == (A / nd) % 10 ) { //高位与低位的比较
                A/= nd;   //用以低位加1
                A++;      //低位加1 
                A*= nd;   //再乘回来
                done = false;
            }
            d = nd;   //表明d和nd都增大10倍
        }
    }
    while (! done);
    return A;
}
int main()
{
    clock_t start,finish;
    double totaltime;
    long a,b;
    scanf("%ld",&a);
    start=clock();//开始计时
    //b=next(a);
    b=getNext(a);
    printf("returns: %ld/n",b);
    finish=clock();  //结束计时
    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("%lf/n",totaltime);  //打印用时
    return 0;
}
 
    但是,运行结果耗时都是0.000000,这就是clock的局限性了吧,它只能精确到15ms,而程序运行用的时间更短,或许是这道题比较简单的缘故吧。不过,在这里可以学到这个函数的使用方法,方便将来的应用。
   其实,这两种方法大同小异吧:
相同点
主要是对输入值进行处理,不断除10取整,比较,直到比较到最高位为止;
不同点:
我的方法:另外声明一个long,对原来的值进行保存,而原来的值,则不断的进行除10取整;
官方的方法:声明了一个bool变量,用来判断是否进行到了最高位;而原来的值,则不断的移位比较而已,通过除10,100,1000...依次比较下去,而bool就用来控制除数的尽头。
 
 
    总的来说呢,这两种方法的区别就是,一是改变原值,但要注意对原值的保存;二是改变除数,但要注意对除数界限的控制。
 

抱歉!评论已关闭.