sdutoj 2609 A-Number and B-Number

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2609

A-Number and B-Number

 

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

    Tom is very interested in number problem. Nowadays he is thinking of a problem about A-number and B-number.
    A-number is a positive integer whose decimal form contains 7 or it can be divided by 7. We can write down the first 10 A-number ( a[i] is the ith A-number) 
         {a[1]=7,a[2]=14,a[3]=17,a[4]=21,a[5]=27,a[6]=28,a[7]=35,a[8]=37,a[9]=42,a[10]=47};
    B-number is Sub-sequence of A-number which contains all A-number but a[k] ( that k is a  A-number.)  Like 35, is the 7th A-number and 7 is also an A-number so the 35 ( a[7] ) is not a B-number. We also can write down the first 10 B-number.

         {b[1]=7,b[2]=14,b[3]=17,b[4]=21,b[5]=27,b[6]=28,b[7]=37,b[8]=42,b[9]=47,b[10]=49};
    Now Given an integer N, please output the Nth B-number

输入

The input consists of multiple test cases.

For each test case, there will be a positive integer N as the description.

输出

For each test case, output an integer indicating the Nth B-number.

You can assume the result will be no more then 2^63-1.

示例输入

1

7

100

示例输出

7

37

470

提示

 

来源

 2013年山东省第四届ACM大学生程序设计竞赛

示例程序

 

 

分析:

一开始想到打表,结果超时咯,后来看了标程用了搜索写的,,,orz

 

超时代码:

 

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 bool fun(int n){

 6     if(n%7==0) return true;

 7     while(n) {

 8         if(n%10==7) return true;

 9         n/=10;

10     }

11     return false;

12 }

13 long long a[100000010];

14 long long  b[100010000];

15 int main(){

16     int i,c=0,cc=0;

17     //freopen("in.txt","r",stdin);

18     for(i=1;i<=100000000;i++)

19       if(fun(i)) a[++c]=i;

20     for(i=1;i<c;i++)

21        if(!fun(i))

22          { b[++cc]=a[i];}

23     long long  n;

24     while(cin>>n){

25         if(n>cc-1) cout<<"??";

26         else 

27         cout<<b[n]<<endl;}

28     return 0;

29 }
View Code

 

 

 

官方标程:

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define ULL unsigned long long

 6 const ULL Maxn=((1uLL<<64uLL)-1);

 7 ULL dp[22][10][2];

 8 int digit[24];

 9 ULL dfs(int pos,int pre,int flag,bool limit){

10     if(pos==-1) return flag||pre==0;

11     if(!limit&&dp[pos][pre][flag] != -1) return dp[pos][pre][flag];

12     int end = limit?digit[pos]:9;

13     int fflag,ppre;

14     ULL ans=0;

15     for(int i = 0;i <= end;i++){

16         fflag = (i==7)||flag;

17         ppre=(pre*10+i)%7;

18         ans+=dfs(pos-1,ppre,fflag,limit&&i==end);

19     }

20     if(!limit) dp[pos][pre][flag]=ans;

21     return ans;

22 }

23 ULL solve(ULL n){//找到n以下有几个A-number

24     int pos = 0;

25     while(n){

26         digit[pos++] = n%10;

27         n /= 10;

28         if(!n) break;

29     }

30     return dfs(pos-1,0,0,1)-1;

31 }

32 ULL find(ULL n){//找到n以下有几个B-number

33     ULL t = solve(n);//表示n包括n以下在A中有t个

34     ULL tt = t - solve(t);//表示t(包括第t个)个A_number中有几个是符合在B中的,一直找到tt刚好等于n为止

35     return tt;

36 }

37 int main()

38 {

39     memset(dp,-1,sizeof(dp));

40     ULL n;

41     while(cin>>n){

42             ULL l = 0, r= Maxn,mid;

43             while(l <= r){

44                 mid = ((r-l)>>1)+l;

45                 if(find(mid)<n) l = mid+1;

46                 else r = mid-1;

47             }

48             ULL ans = r+1;

49             cout<<ans<<endl;

50     }

51     return 0;

52 }
View Code

 

你可能感兴趣的:(number)