XTU 1270 Unique Digit Number(打表,推公式)

数位不同的数
http://202.197.224.59/exam/index.php/problem/read/id/1270
题目描述

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

输入

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

输出

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

样例输入

1
10
100
8877691
样例输出

0
9
120
9876543210

思路:
第一种当然是推公式啊,可是我不会啊(暗中膜400B过的大佬orz)

第二种当然是数位dp+二分查找啊,可是我不会啊。

其实打表是世界上最好的算法。
不难看出不同数字的排列组合应该和数的位数n挂钩,
一位数有10种,
二位数有9 * 9种,
三位数有9 * 9 * 8种,
……
九位数有9 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2种
十位数有9 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1种
于是我们可以开10个数组用来存不同位数的答案,用暴力回溯实现。

#include
using namespace std;
#define ll __int64
ll ans1[10+1];
ll ans2[9*9+1];
ll ans3[9*9*8+1];
ll ans4[9*9*8*7+1];
ll ans5[9*9*8*7*6+1];
ll ans6[9*9*8*7*6*5+1];
ll ans7[9*9*8*7*6*5*4+1];
ll ans8[9*9*8*7*6*5*4*3+1];
ll ans9[9*9*8*7*6*5*4*3*2+1];
ll ans10[9*9*8*7*6*5*4*3*2+1];
int cnt[11];
bool vis[11];
void dfs(int id,int mid,ll x)
{
    if(id==mid)
    {
        if(mid==1){ans1[cnt[1]++]=x;dfs(1,2,x);}
        else if(mid==2){ans2[cnt[2]++]=x;dfs(2,3,x);}
        else if(mid==3){ans3[cnt[3]++]=x;dfs(3,4,x);}
        else if(mid==4){ans4[cnt[4]++]=x;dfs(4,5,x);}
        else if(mid==5){ans5[cnt[5]++]=x;dfs(5,6,x);}
        else if(mid==6){ans6[cnt[6]++]=x;dfs(6,7,x);}
        else if(mid==7){ans7[cnt[7]++]=x;dfs(7,8,x);}
        else if(mid==8){ans8[cnt[8]++]=x;dfs(8,9,x);}
        else if(mid==9){ans9[cnt[9]++]=x;dfs(9,10,x);}
        else if(mid==10){ans10[cnt[10]++]=x;}
    }
    else
    {
        for(int i=0;i<10;i++)
        {
            if(vis[i])continue;
            if(i||x)
            {
                vis[i]=true;
                dfs(id+1,mid,x*10+i);
                vis[i]=false;
            }
        }
    }
}
int main()
{
    fill(cnt,cnt+10,1);cnt[1]=2;
    dfs(0,1,0);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=10;i++)
        {
            if(i==10){printf("%I64d\n",ans10[n-1]);break;}
            else if(n>cnt[i]-1)
                n-=(cnt[i]-1);
            else
            {
                if(i==1){printf("%I64d\n",ans1[n]);break;}
                else if(i==2){printf("%I64d\n",ans2[n]);break;}
                else if(i==3){printf("%I64d\n",ans3[n]);break;}
                else if(i==4){printf("%I64d\n",ans4[n]);break;}
                else if(i==5){printf("%I64d\n",ans5[n]);break;}
                else if(i==6){printf("%I64d\n",ans6[n]);break;}
                else if(i==7){printf("%I64d\n",ans7[n]);break;}
                else if(i==8){printf("%I64d\n",ans8[n]);break;}
                else if(i==9){printf("%I64d\n",ans9[n]);break;}
            }
        }
    }
    return 0;
}
Problem: 1270       User: 2016551517
Memory: 70868K      Time: 640MS
Language: G++       Result: Accepted

转载请注明出处^ ^

你可能感兴趣的:(XTU—程序设计实践网站)