数位不同的数是指所有数位上的数码都不一样的数,比如“123”三个数码1,2,3,都不一样,所以是数位不同的数;但是“1232”中有两个相同的数码2,所以不是。请写一个程序,计算第几个符合条件的数是什么?
每行输入一个整数n(1≤n≤8877691)。
每行输出一个整数,为对应样例的结果。
1
10
100
8877691
0
9
120
9876543210
因为他要求有序的,我就想到了BFS
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
Long res[] = new Long[8877693];
Queue<Long> q = new ArrayDeque<Long>();
q.add(0l);
res[1]=0l;
int k = 2;
while (!q.isEmpty()&&k < 8877693) {
Long t = q.poll();
HashSet<Integer> set = new HashSet<Integer>();
Long qq = t;
while (qq > 0) {
set.add((int) (qq % 10));
qq /= 10;
}
for (int i = 0; i < 10; i++) {
Long e = t * 10 + i;
if (!set.contains(i) && e > 0)
{q.add(e);
res[k++] =e;}
}
}
while (in.hasNext()) {
int n = in.nextInt();
System.out.println(res[n]);
}
}
}
解法二在解法一的基础上新建了一个类,用来存那个数已有的数码,就不用循环求已有的数码了,但还是超时了
import java.util.*;
class Obj {
Long num;
TreeSet<Integer> set;
public Obj(Long num, TreeSet<Integer> set) {
this.num = num;
this.set = set;
}
}
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
Long res[] = new Long[8877693];
Queue<Obj> q = new ArrayDeque<Obj>();
TreeSet<Integer> ss = new TreeSet<Integer>(Arrays.asList(0,1, 2, 3, 4, 5, 6, 7, 8, 9));
Obj o = new Obj(0l, ss);
q.add(o);
res[1] = 0l;
int k = 2;
while (!q.isEmpty() && k < 8877693) {
Obj t = q.poll();
TreeSet<Integer> set = new TreeSet<Integer>(t.set);
for (Integer i : t.set) {
Long e = t.num * 10 + i;
if (e > 0) {
set.remove(i);
q.add(new Obj(e, (TreeSet<Integer>) set.clone()));
res[k++] = e;
set.add(i);
}
}
}
while (in.hasNext()) {
int n = in.nextInt();
System.out.println(res[n]);
}
}
}
搜索出所有结果在排序
import java.util.*;
public class Main {
static Long res[] = new Long[8877691];
static int k = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
boolean[] visited = new boolean[10];
for (int i = 0; i < visited.length; i++) {
visited[i] = true;
res[k++] = (long) i;
dfs((long) i, visited);
visited[i] = false;
}
Arrays.sort(res);
for (int i = 0; i < 100; i++) {
System.out.println(res[i]);
}
while (in.hasNext()) {
int n = in.nextInt();
System.out.println(res[n-1]);
}
}
private static void dfs(Long i, boolean[] visited) {
// TODO Auto-generated method stub
if (i > 9876543210l)
return;
for (int j = 0; j < visited.length; j++) {
if (!visited[j]) {
long t = i * 10 + j;
if (t > 9) {
visited[j] = true;
res[k++] = t;
dfs(t, visited);
visited[j] = false;
}
}
}
}
}
贴一个别人的解法,是本菜狗看不懂的了,以后慢慢啃
#include<stdio.h>
__int64 a[9000000];
int t[9000000]; //不看t的值,t用来标记,记录独特数占了哪些位 也就是用了哪个数
int main()
{
int i,j;
int num=1;
for(i= 1;i<10;i++)
{
a[num] = i;
t[num] =t[num]|(1<<i);
num++;
}
for(i=1;i<num;i++)//num==10
{
for(j=0;j<10;j++)
{
if((1<<j) & ~t[i])//~是按位取反.
{
a[num]=a[i]*10+j;
t[num]=t[i]|(1<<j);
num++;
}
}
}
while(scanf("%d",&i)!=EOF)
printf("%I64d\n",a[i-1]);
}
原文:https://www.cnblogs.com/sellun/p/14878371.html