zhank

网易TopCode复赛

第一题都没调通,果然是平时不练习就不行。

一开始思路就不是很好,想利用数组进行运算过程。前2天看到个高精度计算问题,无从下手,答案是用数组模拟手算。因此使用数组对大数的运算印象很深。拿到第一题,看到数很大(10^17)就想着使用数组手算。结果陷入了极其复杂的逻辑中。

其中主要麻烦的地方有:

  • 重复的是不是首位
  • 重复位是不是9

本来自己练习算法就比较少,使用数组模拟手算也没练习过,再遇到复杂的逻辑,完全不行,整个比赛过程完全陷入debug中。。。

数组模拟手算确实不是一种好方法,至少不是一种首选方法。只有当其他方法不行时,才考虑使用数组模拟手算。

而使用编程语言中的自带整形(或其他),则方便很多:

  • 不用考虑首位问题,
  • 也不用考虑是不是9,应该不应该进位问题

结论:

如果该语言的数据类型可以表示,首选是该类型。如果无法表示,才考虑数组模拟手算。

 

原题:

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


Definition
Class: UnrepeatingNumbers
Method: getNext
Parameters: long
Returns: long
Method signature: long getNext(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

 

使用C#的解决代码(只测试部分数据,不能保证100%正确),思路很清晰,也没有复杂的逻辑:

class UnrepeatingNumbers
{
    private bool isAdd = false;

    public long getNext(long A)
    {
        bool isSameExist = false;
        long temp = isAdd ? A :A + 1;
        long result = temp;
        isAdd = true;

        int last = -1;
        int index = 0;
        int first = 0;
        long addNum = 1;

        while (temp > 0)
        {
            if (temp % 10 == last)
            {
                isSameExist = true;
                first = index;
            }
            else
                last = (int)(temp % 10);

            temp /= 10;
            index++;
        }

        for (int i = 0; i < first - 1; i++)
        {
            addNum *= 10;
        }

        if (isSameExist)
        {
            result = result - (result % addNum) + addNum;
            return getNext(result);
        }
        else
            return result;
    }

posted on 2009-06-21 23:02  zhank  阅读(587)  评论(0编辑  收藏  举报

导航