题意:找出给定区间内首数字为1的数字。
做法:基本数位DP,可是出现了一堆小错误 。。。
#include<cstdio>
#include<cstring>
#define LL long long
const int LMT=1002;
LL have[LMT],tem[LMT],num[20],left[LMT],right[LMT];
/***********
一开始把统计区间内符合的数字给
搞错了
****/
double dp[LMT];
void init(void)
{
int i;
LL use = 1; //fuck 这里的use
tem[1]=1;
for(i=2, use=10;i<20; ++i, use*=10)
tem[i]=use+tem[i-1];
}
LL treat(LL x)
{
if(0 == x)return 0;
LL res=0,rev_x=0;
int i = 0, end;
do
num[i++]=x%10;
while(x/=10);
res+=tem[i-1];end=i;
if (num[end - 1] > 1) return tem[end];
for(i = end - 2; i >=0; --i)
{
rev_x *= 10;
rev_x += num[i];
}
return res + rev_x + 1;
}
int main(void)
{
int N,i,j, k;
double ans=0;
init();
scanf("%d",&N);
for(i=1;i<=N;i++)
{
scanf("%I64d%I64d",&left[i],&right[i]);
have[i]=treat(right[i])-treat(left[i] - 1);
}
scanf("%d",&k);
dp[0]=1.0;
for(i=1;i<=N;++i)
for(j=i;j>=0;--j)
{
dp[j]=dp[j]*(right[i]-left[i]+1-have[i])/(right[i]-left[i]+1);
if(j)
dp[j]+=dp[j-1]*have[i]/(right[i]-left[i]+1);
}
for(i=0;i<=N;i++)
if(i*100>=N*k)//这里都会错啊,没乘100
ans += dp[i];
printf("%.15f\n",ans);
return 0;
}