Codeforces Round #460 (Div. 2) B Perfect Number(二分+数位dp)
B. Perfect Number
time limit per test
2 secondsmemory limit per test
256 megabytesinput
standard inputoutput
standard outputWe consider a positive integer perfect, if and only if the sum of its digits is exactly 1010. Given a positive integer kk, your task is to find the kk-th smallest perfect positive integer.
Input
A single line with a positive integer kk (1≤k≤100001≤k≤10000).
Output
A single number, denoting the kk-th smallest perfect integer.
Examples
input
Copy
1
output
Copy
19
input
Copy
2
output
Copy
28
Note
The first perfect integer is 1919 and the second one is 2828.
题意:求出第k个各位数和为10的数
题解:本题k的范围比较小,所以暴力可以解决
但是当范围大的时候,就要用数位dp了
数位dp记录的是小于某个数的符合条件的数有多少个
用二分去枚举
代码:
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<queue> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long long ll; typedef pair<int,int> PII; #define mod 1000000007 #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second //head int k; ll a[10005]; bool check(ll x) { ll ans=0; while(x){ ans+=x%10; x/=10; } return ans==10; } int main() { scanf("%d",&k); int p=0; for(int i=0;i<11000006;i++) { if(check(i)) { a[++p]=i; } } printf("%lld\n",a[k]); return 0; }
#include<bits/stdc++.h> using namespace std; int k; bool check(int x) { int ans=0; while(x){ ans+=x%10; x/=10; } return ans==10; } int main() { scanf("%d",&k); int p=0; for(int i=0;i<11000006;i++) { if(check(i)) { p++; if(p==k) { printf("%d\n",i); } } } return 0; }
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<queue> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long long ll; typedef pair<int,int> PII; #define mod 1000000007 #define INF 0x3f3f3f3f #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second //head int k; int bit[11]; int dp[20][11];//表示到第i位,数位和为j的个数 int dfs(int pos,int sum,bool limit) { if(pos==-1) return sum==10; if(sum>10)return 0; if(!limit&&dp[pos][sum]!=-1)return dp[pos][sum]; int ans=0; int up=limit?bit[pos]:9; for(int i=0;i<=up;i++) { ans+=dfs(pos-1,sum+i,limit&&(i==up)); } if(!limit) dp[pos][sum]=ans; return ans; } int calc(int x) { int len=0; while(x) { bit[len++]=x%10; x/=10; } return dfs(len-1,0,true); } int main() { memset(dp,-1,sizeof(dp)); while(~scanf("%d",&k)) { int lb=0,ub=INF; int ans=0; while(ub-lb>1){ int mid=(lb+ub)/2; if(calc(mid)<k) lb=mid; else ans=mid,ub=mid; } printf("%d\n",ans); } return 0; }