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.
Now Given an integer N, please output the Nth B-number
输入
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.
示例输入
17100
示例输出
737470
提示
来源
示例程序
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll unsigned long long
#define mid ((l+r)>>1)
using namespace std;
ll dp[19][2][7];
int data[19];
inline ll dfs(int len,bool is_7,int mod_7,int limit){
if(!len)return (is_7||(mod_7==0));
if(!limit&&dp[len][is_7][mod_7]!=-1)return dp[len][is_7][mod_7];
int ed=limit?data[len]:9;
ll ans=0;
for(int i=0;i<=ed;++i)
ans+=dfs(len-1,is_7||i==7,(mod_7*10+i)%7,limit&&i==ed);
return limit?ans:dp[len][is_7][mod_7]=ans;
}
inline ll fun(ll n){
int len=0;
while(n){
data[++len]=n%10;
n/=10;
}
return dfs(len,0,0,1)-1;
}
void doit(ll n){
ll l=n,r=((long long)1<<63);
ll add;
while(l<r){
ll tmp=mid-fun(mid);
if(tmp==n){
for(ll k=l;k<=mid;++k)
if(k-fun(k)==n){
add=fun(k);
break;
}
break;
}
if(tmp>n)r=mid;
else l=mid;
}
l=0,r=((long long)1<<63);
n+=add;
while(l<r){
ll tmp=fun(mid);
if(tmp==n){
for(ll k=l;k<=mid;++k)
if(fun(k)==tmp){
cout<<k<<'\12';
return;
}
}
if(tmp<n)l=mid;
else r=mid;
}
}
int main(){
ll n;memset(dp,-1,sizeof(dp));
ios::sync_with_stdio(false);
while(cin>>n)doit(n);
return 0;
}