从Recycled Numbers谈字符串和数字的操作便利性

本文深入探讨了CodeJam上一道关于数字循环移位的问题,阐述了解题思路并提供了一个简洁高效的代码解决方案。重点在于通过数字直接操作避免了复杂字符串处理,展现了在数字与字符串操作中选择最佳方法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是CodeJam上的一道题目:

Problem

Do you ever become frustrated with television because you keep seeing the same things, recycled over and over again? Well I personally don't care about television, but I do sometimes feel that way about numbers.

Let's say a pair of distinct positive integers (nm) is recycled if you can obtain m by moving some digits from the back of n to the front without changing their order. For example, (12345, 34512) is a recycled pair since you can obtain 34512 by moving 345 from the end of 12345 to the front. Note that n and m must have the same number of digits in order to be a recycled pair. Neither n nor m can have leading zeros.

Given integers A and B with the same number of digits and no leading zeros, how many distinct recycled pairs (nm) are there with A ≤ n < m ≤ B?

Input

The first line of the input gives the number of test cases, TT test cases follow. Each test case consists of a single line containing the integers A and B.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1), and y is the number of recycled pairs (nm) with A ≤ n < m ≤ B.

Limits

1 ≤ T ≤ 50.
A and B have the same number of digits.

Small dataset

1 ≤ A ≤ B ≤ 1000.

Large dataset

1 ≤ A ≤ B ≤ 2000000.

Sample


Input 
 

Output 
 
4
1 9
10 40
100 500
1111 2222
Case #1: 0
Case #2: 3
Case #3: 156
Case #4: 287

Are we sure about the output to Case #4?

Yes, we're sure about the output to Case #4.


题目不难,唯一可能出现问题的地方在于遇到类似case4这种情况时,需要对得到的数字对进行判断,避免重复。

解决思想大多是对于每个属于[A,B)的x,找出是否存在一个属于(x,B]的数字是x通过循环移位后可以得到。

关于判断循环移位的到的数字集问题,有一个非常简单的办法就是将其数字加倍。具体做法就是,如果x为1234,则移位实现的数字一定是12341234的4位子串。这样就非常简单了。


官方给出了一个针对Small Input的代码,如下:

int solve(int A, int B) {
    int power = 1, temp = A;
    while (temp >= 10) {
        power *= 10;
        temp /= 10;
    }
    int result = 0;
    for (int n = A; n <= B; ++n) {
        temp = n;
        while (true) {
            temp = (temp / 10) + ((temp % 10) * power);
            if (temp == n)
                break;
            if (temp > n && temp <= B)
                result++;
        }
    }
    return result;
}

代码简短,逻辑清楚,非常漂亮。尤其值得一提的是其针对数字的直接操作,即

temp = (temp / 10) + ((temp % 10) * power);

不用将数字先用itoa转换成字符串,再在拼接字符串后提取子串,再用atoi转成数字进行判断。而是,直接用一步基本的加减操作得到,省去了很多麻烦和代码,虽谈不上多么思想精妙,但是这种思路,思考方式仍旧非常值得学习。

字符串和数字操作中有共同点,不同情况下不同方法的效率有巨大差别,针对此类问题而言,数字操作简单精妙!以后遇到类似需要操作数字型字符串或数字时,脑袋里要有两个角度,看一看究竟用数字简单还是字符串简单。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值