进饮料
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
2
-
描述
-
Eric开了一家饮料店,一天他进货的的时候发现有一种饮料在进行一个促销活动。具体如下:每一瓶饮料上面有一个号码,当且仅当这个号码的首尾数字相同则可以进行一次随机抽奖(当然奖品是丰盛的)。 另外他还发现一辆车上运来饮料的标号居然是连续的(从a到b)。因为他打算进这种饮料,所以他想知道在这一车的饮料中能进行抽奖的概率是多少(保留三位小数)。
-
输入
- 一行两个正整数 1 <= a <= b <= 10^18 直到EOF,最多100行 输出
- 一行一个数字,保留三位小数 样例输入
-
1 2 47 1024 2 47
样例输出
-
1.000 0.100 0.261
题目找规律,思路:
一个数假如为2567,求0--2567满足抽奖条件的个数。
首先0--10有9个
10--100 9个
100--1000 90个
1000--10000 900个
一次类推则:
0---10 9个
0---100 18个
0---1000 108个
0---10000 1008个
可先求出0--1000的为108个。
然后1000--2000共9*10个
2000--2567 为56+1个
共108+90+57=155个
详细看代码:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> using namespace std; long double a[100],b[105]; void read() { a[1]=9,a[2]=18,a[0]=0; for(int i=3;i<22;i++) a[i]=pow(10,i-1)+8; } string to_string(long long x) { string ans; while(x) { ans+=(x%10+'0'); x/=10; } reverse(ans.begin(),ans.end()); return ans; } long double solve(string x,long long y) { if(x.size()<=2) return b[y]; long double ans=0; ans+=a[x.size()-1]; ans+=(x[0]-'0'-1)*pow(10,(x.size()-2)); long long cmp=0; for(int i=1;i<x.size()-1;i++) cmp=cmp*10+(x[i]-'0'); ans+=cmp; if(x[x.size()-1]>=x[0]) ans++; return ans; } void isit() //0--100暴力 { b[0]=0; memset(b,0,sizeof(b)); for(int i=1;i<=100;i++) { int en=i%10,k=i/10,wei=1; while(k) { k/=10; wei*=10; } if(i/wei==en) b[i]=b[i-1]+1; else b[i]=b[i-1]; } //printf("%lld %lld\n",b[0],b[1]); } int main() { //freopen("rad.txt","r",stdin); //freopen("O.txt","w",stdout); long long x,y; isit(); read(); while(~scanf("%lld%lld",&x,&y)) { string st,se; st=to_string(x-1),se=to_string(y); long double ans_x=solve(st,x-1),ans_y=solve(se,y); //printf("%lf %lf\n",ans_x,ans_y); double sum=(double)(ans_y-ans_x)/(double)(y-x+1); printf("%.3lf\n",sum); } return 0; } //999999999999999999 1000000000000000000