记录编号 231763 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [ZOJ 2599]高级字典序 最终得分 100
用户昵称 Gravatar张灵犀不和我一般见识真可怕呢(笑 是否通过 通过
代码语言 C++ 运行时间 0.118 s
提交时间 2016-02-27 19:03:35 内存使用 0.31 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int SIZEL=30,SIZEN=210;
typedef unsigned long long LL;
LL f[SIZEL][SIZEN]={0};//长度为L,数位和为N的数的个数
LL Pow10[SIZEL]={0};
void prepare()
{
	f[0][0]=1;
	for(int i=1;i<=20;i++)
	{
		f[i][0]=1;
		for(int j=1;j<=200;j++)
		{
			f[i][j]=0;
			for(int k=0;k<=9;k++)
			{
				if(j<k) break;
				f[i][j]+=f[i-1][j-k];
			}
		}
	}
	Pow10[0]=1;
	for(int i=1;i<=20;i++) Pow10[i]=10*Pow10[i-1];
}
int digsum(LL x)
{
	int ans=0;
	while(x)
	{
		ans+=x%10;
		x/=10;
	}
	return ans;
}
int dignum(LL x)
{
	int ans=0;
	while(x)
	{
		ans++;
		x/=10;
	}
	return ans;
}
LL calc(LL N,int s)//数位之和小于s且数的大小小于N
{
	int len=dignum(N);
	LL ans=0;
	if(digsum(N)==s) ans++;
	for(int i=len;i>=1;i--)
	{
		int now=(N/Pow10[i-1])%10;
		for(int j=0;j<now&&j<=s;j++)
		{
			ans+=f[i-1][s-j];
		}
		if(s<now) break;
		else s-=now;
	}
	return ans;
}
LL sum(LL N,LL K,int s)//如你所见,数位之和小于s且字典序小于K
{
	LL ans=0;
	int LK=dignum(K),LN=dignum(N);
	for(int i=1;i<s;i++) ans+=calc(N,i);
	if(K==0) return ans;
	LL tem=K;
	for(int i=LK;i>=1;i--)
	{
		ans+=calc(tem,s);
		ans-=f[i-1][s];
		tem/=10;
	}
	tem=K*10;
	for(int i=LK+1;i<=LN;i++)
	{
		ans+=calc(min(N,tem-1),s);
		ans-=f[i-1][s];
		tem*=10;
	}
	return ans;
}
LL getnumber(LL N,LL K)
{
	int i=1;
	LL tem=0;
	while(true)
	{
		LL now=calc(N,i);
		if(tem+now<K) tem+=now;
		else break;
		i++;
	}
	LL ans=0;
	int s=i;
	while(true)
	{
		ans*=10;
		int j=0;
		while(j<=9)
		{
			//cout<<ans+j<<" "<<sum(N,ans+j,s)<<endl;
			if(sum(N,ans+j,s)>=K) break;
			j++;
		}
		//cout<<ans<<" "<<j<<endl;
		ans=ans+j;
		//cout<<ans<<endl;
		if(sum(N,ans,digsum(ans))==K) break;
		ans--;
	}
	return ans;
}
void work()
{
	LL n,k;
	cin>>n>>k;
	cout<<sum(n,k,digsum(k))<<endl;
	cout<<getnumber(n,k)<<endl;
}
int main()
{
	freopen("Lexicographical.in","r",stdin);
	freopen("Lexicographical.out","w",stdout);
	prepare();
	work();
	return 0;
}