首先是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 (n, m) 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 (n, m) are there with A ≤ n < m ≤ B?
Input
The first line of the input gives the number of test cases, T. T 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 (n, m) 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
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转成数字进行判断。而是,直接用一步基本的加减操作得到,省去了很多麻烦和代码,虽谈不上多么思想精妙,但是这种思路,思考方式仍旧非常值得学习。
字符串和数字操作中有共同点,不同情况下不同方法的效率有巨大差别,针对此类问题而言,数字操作简单精妙!以后遇到类似需要操作数字型字符串或数字时,脑袋里要有两个角度,看一看究竟用数字简单还是字符串简单。