站外题求调
  • 板块学术版
  • 楼主E1_de5truct0r
  • 当前回复5
  • 已保存回复5
  • 发布时间2021/4/10 11:26
  • 上次更新2023/11/5 00:47:06
查看原帖
站外题求调
195198
E1_de5truct0r楼主2021/4/10 11:26

题目:

loj的:Link

hdu的:Link (两道题目完全一样,只不过网站不同)

解法:暴力或者数位DP

我的暴力AC了,不过数位DP WA 了,求大佬指教

我的代码:

#include <bits/stdc++.h>
using namespace std;
int dp[15][15],digit[15];
//dp[i][j]表示i位数中,首位为j的数满足条件的个数
int calc(int len) //计算[0, 10^(len+1)-1]之间的满足条件的数的个数
{
	int ans=0;
	for(int i=len;i>=1;i--)
	{
		for(int j=0;j<digit[i];j++)
			if(j!=4) ans+=dp[i][j];
		if(digit[i]==4) ans--; //特判
		if(digit[i]==6) ans-=dp[i][2]; //特判
	}
	return ans;
}
int main()
{
	//预处理
	dp[0][0]=1;
	for(int i=1;i<=10;i++)
		for(int j=0;j<=9;j++)
			for(int k=0;k<=9;k++)
				if(j!=4 && !(k==2 && j==6)) dp[i][j]+=dp[i-1][k];
   //读入+计算
	int L,R;
	while(~scanf("%d%d",&L,&R) && L && R)
	{
		int calcL,calcR,len1=0,len2=0;L--;
		while(L){digit[++len1]=L%10; L/=10;}
		calcL=calc(len1); //拆分每一位
		memset(digit,0,sizeof(digit));
		while(R){digit[++len2]=R%10; R/=10;}
		calcR=calc(len2); //拆分每一位
		cout<<calcR-calcL<<endl; //题目求的是[L,R],所以要用[0,R]-[0,L-1]。
	}
	return 0;
}
2021/4/10 11:26
加载中...