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
原文地址:https://www.cnblogs.com/jeff-wgc/p/4468320.html