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

来源:互联网 发布:淘宝铁观音怎么选 编辑:程序博客网 时间:2024/09/21 06:36

数位不同的数
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<bits/stdc++.h>using namespace std;#define ll __int64ll 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: 2016551517Memory: 70868K      Time: 640MSLanguage: G++       Result: Accepted

转载请注明出处^ ^

原创粉丝点击