题意是由4和7组成的数字称为lucky number,给你两个区间 在这两个区间里随机选两个数字作为左区间和右区间。问你在这个区间中lucky number个数为k个的期望为多少。
这题的思路就是先预处理出来所有的lucky number,遍历每个lucky number。 算出符合提议的情况有多少种。然后除以情况总数就好了。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef __int64 ll;
vector<ll> num;
ll lim=5e8;
ll nu[100000],tot;
void dfs(ll x){
num.push_back(x);
if(x<lim){
dfs(x*10+4);
dfs(x*10+7);
}
}
void init(){
dfs(0);
tot=num.size();
for(int i=0;i<=num.size();i++)
{
nu[i]=num[i];
}
sort(nu+1,nu+1+tot);
/*for(int i=tot-10;i<=tot;i++)
cout<<nu[i]<<endl;*/
}
int main()
{
ll pl,pr,vl,vr,k,ans=0;
ll l,r;
init();
cin>>pl>>pr>>vl>>vr>>k;
for(int i=2;i<=tot;i++){
if(i+k-1>tot) break;
if(pl<=nu[i]&& nu[i+k-1]<=vr){
if(nu[i-1]<=pr && nu[i+k]>=vl){
l=pl;r=vr;
if(nu[i-1]>=pl) l=nu[i-1]+1;
if(nu[i+k]<=vr) r=nu[i+k]-1;
//if(vl==r && pr==r) ans--;
// cout<<l<<" "<<pr<<" "<<vl<<" "<<r<<endl;
ans+=min((pr-l+1),(nu[i]-l+1))*min((r-vl+1),(r-nu[i+k-1]+1));
}
}
if(vl<=nu[i]&& nu[i+k-1]<=pr){
if(nu[i-1]<=vr && nu[i+k]>=pl){
l=vl;r=pr;
if(nu[i-1]>=vl) l=nu[i-1]+1;
if(nu[i+k]<=pr) r=nu[i+k]-1;
// cout<<pl<<" "<<r<<" "<<l<<" "<<vr<<endl;
ans+=min((vr-l+1),(nu[i]-l+1))*min((r-pl+1),(r-nu[i+k-1]+1));
}
}
}
for(int i=2;i<=tot;i++){
if(nu[i]>=pl&&nu[i]<=pr&&nu[i]>=vl&&nu[i]<=vr&&k==1)ans--;
}
printf("%.12lf\n",(double)ans/(pr-pl+1)/(vr-vl+1));
}