Olympiad
2017-08-03 20:33:21
You are one of the competitors of the Olympiad in numbers. The problem of this year relates to beatiful numbers. One integer is called beautiful if and only if all of its digitals are different (i.e. 12345 is beautiful, 11 is not beautiful and 100 is not beautiful). Every time you are asked to count how many beautiful numbers there are in the interval [a,b] (a≤b)[a,b] (a≤b). Please be fast to get the gold medal!
InputThe first line of the input is a single integer T (T≤1000)T (T≤1000), indicating the number of testcases.
For each test case, there are two numbers aa and bb, as described in the statement. It is guaranteed that 1≤a≤b≤1000001≤a≤b≤100000.
OutputFor each testcase, print one line indicating the answer.
Sample Input
2
1 10
1 1000
Sample Output
10 738
题目大意 : 求从1——n的数中每一位数不重复的个数。
题目分析 : 这道题最重要的是分析算法时间复杂度,因为时间复杂的大小决定了你的代码书写方式。就比如说:这道题的1≤a≤b≤106我们采用较为常规的做法,也就是暴力求解
首先预处理,将无重复的数标记为1,重复的数标记为0,我们必然要用到for循环语句一个一个去判断,在判断的方法中,我们的数只有6位数,也最多while循环6次。假设我们
全部取最坏的情况,即每一次for包含6次while,我们总共要执行6*106 ,最后相加不过也是106,至此总共加起来不过7*106,而计算的一秒运算能力在107~108左右,正好满足
条件。 如果b的范围再大一点107暴力解决的方式就不可行了,就必须重新优化算法。
题目收获 : 算法时间复杂度的重要性。
代码 :
#include <iostream> #include <set> #define maxn 100005 using namespace std; int num[maxn]; int check(int x) { set<int> op; while (x) { int mid = x % 10; if (!op.count(mid)) op.insert(mid); else return 0; x /= 10; } return 1; } void doit() { for (int i = 1; i <= maxn - 5; i++) num[i] = check(i); for (int i = 2; i <= maxn - 5; i++) num[i] += num[i - 1]; }