您的位置:首页 > 其它

Acdream sgx和路飞(二分搜索)

2014-07-11 11:33 393 查看
考虑二分搜索,并且二分是判断左到中间那个数是否存在,所以只要判断1到n和为m的最大数是否相同。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int x[21],s[21],y[21];
int  vv(long long n){
int p;
p=0;
while(n>0){
if(p==0){
s[0]=n%10;
}
else{
s[p]=s[p-1]+n%10;
}
x[p++]=n%10;
n=n/10;
}
return p;
}
long long solve(long long m,int n){
int i,j,p;
long long v,u;
p=vv(m);
if(s[p-1]>=n){
for(i=p-1;i>=0;i--){
if(n==0){
y[i]=0;continue;
}
if(x[i]>=n){
y[i]=n;
n=0;
continue;
}
y[i]=x[i];
n=n-x[i];
}
v=0;u=1;
for(i=0;i<p;i++){
v+=u*y[i];
u=u*10;
}
return v;
}
for(i=p-1;i>=0;i--){
if(x[i]==0) continue;
if(s[p-1]-s[i]+x[i]-1+9*i<n){
break;
}
}
if(i==p-1) return -1;
while(i+1<=p-1&&x[i+1]==0)
i++;
for(j=p-1;j>i+1;j--){
y[j]=x[j];
n=n-x[j];
}
y[i+1]=x[i+1]-1;
n=n-y[i+1];
for(j=i;i>=0;j--){
if(n>=9){
n=n-9;
y[i]=9;
}
else{
break;
}
}
if(j>=0){
y[j]=n;
}
j--;
for(;j>=0;j--)
y[j]=0;
u=0;
v=1;
for(i=0;i<p;i++){
u+=v*y[i];
v=v*10;
}
return u;
}
long long get( long long a, long long b ,int n){
long long le,ri,mid;
le=a;
ri=b;
while(le<=ri){
mid=(le+ri)/2;
if(solve(mid,n)-solve(le-1,n)==0){
le=mid+1;
}
else{
ri=mid-1;
}
}
return le;
}
int main()
{
int n;
long long a,b;
while(scanf("%lld%lld%d",&a,&b,&n)!=EOF){
printf("%lld\n",get(a,b,n));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: