牛客小白月赛7-D 明七暗七

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/82843268

地址:https://www.nowcoder.com/acm/contest/190/D

思路:数位DP+二分。利用数位DP可以求出从1到n的满足条件的个数,而对于求具体的数字,则可以用二分查找来求解

dp[i][j][k]: 前i位余数为j,是否有7的个数

Code:

#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;

LL n,m;
int a[20];
LL dp[20][10][2];

LL Find(LL p);
LL DFS(int k,int mod,int boo,int bo);
int main()
{
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		memset(dp,-1,sizeof(dp));
		LL l=n,r=1e14,t=Find(n);
		while(l<=r){
			LL h=(l+r)/2;
			if(Find(h)-t>=m)	r=h-1;
			else	l=h+1;
		}
		cout<<l<<endl;
	}
	
	return 0;
}

LL Find(LL p)
{
	int pre=0;
	while(p){
		a[pre++]=p%10;
		p/=10;
	}
	return DFS(pre-1,0,0,1);
}

LL DFS(int k,int mod,int boo,int bo)	//第k位,余数mod,boo是否有7,bo是否为p 
{
	LL ans=0;
	if(k==-1)	ans=(!mod)||boo;
	else	if(dp[k][mod][boo]!=-1&&!bo)	ans=dp[k][mod][boo];
	else{
		int pre=bo?a[k]:9;
		for(int i=0;i<=pre;++i)
			ans+=DFS(k-1,(mod*10+i)%7,boo||i==7,bo&&i==a[k]);
		if(!bo)	dp[k][mod][boo]=ans;
	}
	return ans;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/82843268
今日推荐