XTU OJ Unique Digit Number

数位不同的数

题目描述

数位不同的数是指所有数位上的数码都不一样的数,比如“123”三个数码1,2,3,都不一样,所以是数位不同的数;但是“1232”中有两个相同的数码2,所以不是。请写一个程序,计算第几个符合条件的数是什么?

输入

每行输入一个整数n(1≤n≤8877691)。

输出

每行输出一个整数,为对应样例的结果。

样例输入

1
10
100
8877691

样例输出

0
9
120
9876543210

思路分析:看了网上巨佬的思路和代码,这道题主要是就是按照顺序进行构造符合题意的数字(还是太菜了),采用DFS算法 

#include 
#include 
__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]);
	}

}

你可能感兴趣的:(刷题,OJ,算法,深度优先)