#1301 : 筑地市场
时间限制:7000ms
单点时限:1000ms
内存限制:256MB
描述
筑地市场是位于日本东京都中央区筑地的公营批发市场,为东京都政府设置的中央批发市场之一,亦是日本最大的鱼市场。其规模之大与知名度之广,不只是东京,更是日本首屈一指的批发市场。全球百分之五十的金枪鱼,从世界的各地被运往这里,在每天的清晨,进行着繁忙的拍卖,它们是寿司中最不可或缺的食材,如何能够买到上等的金枪鱼,成为了每家寿司店都关注的大事。
当地的鱼贩,会取出鱼腹的一小块进行观察,以辨别鱼品质的好坏...
我们将取出的小块可以看成是一个十进制数字串(没有前缀0),其中包含数字4或者7的数字串,被认为是好的。岛娘想知道所有的数字串中,数字串转为十进制数后排第 k 小(从1开始)的好字符串是多少,你可以帮助她吗?
输入
输入数据包含一行一个整数 k(k ≤ 1018)。
输出
输出数据包含一行,表示对应的十进制数字串。
- 样例输入
-
19
- 样例输出
-
54
分析:二分+裸数位dp;
代码:#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #define rep(i,m,n) for(i=m;i<=n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") const int maxn=1e5+10; const int N=5e4+10; const int M=N*10*10; using namespace std; inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline void umax(ll &p,ll q){if(p<q)p=q;} inline void umin(ll &p,ll q){if(p>q)p=q;} int n,m,k,t,num[20],pos; ll dp[20][2],p; ll dfs(int pos,int x,int y) { if(pos<0)return x; if(y&&dp[pos][x]!=-1)return dp[pos][x]; int now=y?9:num[pos],i; ll ret=0; rep(i,0,now) { ret+=dfs(pos-1,x||i==4||i==7,y||i<num[pos]); } return y?dp[pos][x]=ret:ret; } ll gao(ll x) { pos=0; while(x)num[pos++]=x%10,x/=10; return dfs(pos-1,0,0); } int main() { int i,j; memset(dp,-1,sizeof(dp)); scanf("%lld",&p); ll l=1,r=9e18,ret; while(l<=r) { ll mid=l+r>>1; if(gao(mid)>=p)ret=mid,r=mid-1; else l=mid+1; } printf("%lld ",ret); return 0; }