zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    hdu 6702 ^&^ 位运算
    hdu 6709 Fishing Master 贪心
    hdu 6704 K-th occurrence 二分 ST表 后缀数组 主席树
    hdu 1423 Greatest Common Increasing Subsequence 最长公共上升子序列 LCIS
    hdu 5909 Tree Cutting FWT
    luogu P1588 丢失的牛 宽搜
    luogu P1003 铺地毯
    luogu P1104 生日
    luogu P1094 纪念品分组
    luogu P1093 奖学金
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4468320.html
Copyright © 2011-2022 走看看