数位不同的数
题目描述
数位不同的数是指所有数位上的数码都不一样的数,比如“123”三个数码1,2,3,都不一样,所以是数位不同的数;但是“1232”中有两个相同的数码2,所以不是。请写一个程序,计算第几个符合条件的数是什么?
输入
每行输入一个整数n(1≤n≤8877691)。
输出
每行输出一个整数,为对应样例的结果。
样例输入
1 10 100 8877691
样例输出
0 9 120 9876543210
思路分析:看了网上巨佬的思路和代码,这道题主要是就是按照顺序进行构造符合题意的数字(还是太菜了),采用DFS算法
#include <stdio.h>
#include <math.h>
__int64 num[8877711];
int flag = 1;//判断满足题意的某个数的序号
int ischeck[10] = { 0 };//检查某一个数字是否使用
void dfs(int n, int m, __int64 ans) {
if (n == m - 1) {//因为调用时候是m+1,在上一次调用时m已经指向了n,然后这次调用是m+1,所以要判断是否指向最后一位,就应该看n是否为m-1
num[flag] = ans;
flag++;
return;
}
for (int i = 0; i <= 9; i++) {//某一位有多少种数字
if (n != 1 && m == 1 && i == 0) {
continue;//如果说该数不为一位数,一个指针m指向第一个数字,被m指向的数字为0
//那么就退出寻找0,在该位数寻找数字1,因为开头为0是没有意义的
}
if (ischeck[i] == 0) {//如果说数字i没有搜索过
ischeck[i] = 1;//那么此时开始搜索,开始对1进行搜索
dfs(n, m + 1, ans * 10 + i);//再次调用该函数,将该数的指针指向下一位,然后数字就
ischeck[i] = 0;//递归调用完后重置所有数据
}
}
//这个算法并不是让你一一进行比对,而是有一定顺序不会重复也不会漏数字去构造出复合题意的数据,并标记
//这是第几个数字
//我先枚举进行说明
//比方说3位数先判断0,因为开头为0,m==1,但是我们实际上没有搜索过0,所以 i = 1,开始在第一位搜索1,
//1没有搜索过,然后m+1进入下一位,此时我们的ans应该为1,代表构造的数为1
//然后m+1,进入下一位,因为是再一次调用该函数,在第二位上继续搜索数字,因为这是新调用的函数
//所以说i还是为0,代表第二位还是从0开始搜索
//因为最开始我们并没有搜索过0,而是直接退出,然后说明0的标记为0,此时我们搜索它,将其标记为1
//然后继续调用该函数进入下一位的搜索,此时的ans = 1*10+0 = 10,构造出来的第个数字为10
//所以说我们是这样构造的100,101,102... 120 121....这样
}
int main() {
int n;
for (int i = 1; i <= 10; i++) {
dfs(i, 1, 0);//从第1位数开始进行DFS搜索
}
while (scanf("%d", &n) != EOF) {
printf("%I64d\n", num[n]);
}
}