aoj 600 数字游戏

转载 2016年08月28日 15:42:35

题目链接:http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=600


题目描述:

Description
cxlove对数字情有独钟,最近又开始玩一个有趣的数字游戏。
首先我们定义一种Lucky number:最高位为1的数字(10进制)。
接下来,会给你n个区间,[Li,Ri]
随机从每一个区间内取出1个整数。
问取出的这n个数中至少有K%是Lucky number的概率是多少。

Input
一个整数 T,表示T组数据。(1<=T<=50)
一个整数n,表示区间的个数 (1<=n<=1000)
接下来n行,每一行两个整数Li,Ri表示区间[Li,Ri],并且保证(1<=Li<=Ri<=10^18)
最后一行是一个整数k (0<=k<=100)

Output
一个实数,表示至少有k%是Lucky Number的概率,小数点后保留6位。

Sample Input
Original Transformed
2
1
1 2
50
2
1 2
9 11
50

Sample Output
Original Transformed
0.500000
0.833333

Source
安徽大学第五届ACM/ICPC程序设计竞赛 现场赛


解题思路:转自http://blog.csdn.net/j_sure/article/details/41624065

警示1:整数的n次方,再也不要用自带的pow()函数。自己写!心情好还能写个快速幂。因为自带的pow()函数是double类型的,精度损失非常大

警示2:区间右端点减去区间左端点,左端点要先减去1。防止左端点被减掉。

警示3:一定要根据dp数组的状态描述仔细地进行初始化。

设dp[i][j]表示前i个区间选到了j个幸运数字的概率。

那么dp[0][0] = 1(0个区间一定是0个幸运数字)

设每个区间选择到幸运数字的概率是v[i]

状态转移方程为:

dp[i][j] = dp[i-1][j-1] * v[] + dp[i-1][j] * (1-v[])

要么是第i个区间选择到了幸运数字,要么是前i-1个区间已经选够了j个幸运数字。

由此我们需要初始化dp[i][0]。因为1个幸运数字都没有选到,所以一路乘即可。

得到至少k%个幸运数字其实就是n * k%想上取整而已。设至少p个。之后把dp[][p] + dp[][p+1] + ... + dp[][n]即可。

现在剩下的问题是预处理区间内幸运数字的个数。这样就可以尽快查询到。(10^18很大啊)。

0~9:1个

10~99:10个

100~999:100个

......

取出左右端点将它们“剪裁”成上述片段即可。这里有用到前缀和。


AC代码:

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;
long long int T,n,k,num;
double dp[1005][1005];
double rate[1005];
long long int l,r;
long long int ll[20];//ll[i]代表最长i位数字所拥有的以1开头的数字的个数

long long int power(long long int x,long long int y)//x^y
{
    long long int j=1;
    while(y--)
        {
            j*=x;
        }
    return j;
}

void Init()
{
    ll[0]=0;
    for(long long int i=1;i<=18;i++)
    {
        ll[i]=power(10,i-1);
        ll[i]+=ll[i-1];
    }
}

long long int getnum(long long int x)
{
    char s[25];
    sprintf(s,"%lld",x);
    int len=strlen(s);
    if(len==1)
        {
            return x?1:0;
        }
    if(s[0]=='1')
        return x-power(10,len-1)+1+ll[len-1];
    else
        return ll[len];
}

//用这个来求解1开头的数字的个数会超时
/*long long int zg(long long int k)
{
    long long int p=k;
    long long int w=0,q=1;
    while(p)
    {
        w++;
        p/=10;
    }
    for(long long int i=1;i<=w-1;i++)
        q*=10;
    if(k/q==1)
        return 1;
    else
        return 0;
}*/

int main()
{
    Init();
    scanf("%lld",&T);
    while(T--)
    {
        //memset(rate,0,sizeof(rate));
        scanf("%lld",&n);
        for(long long int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&l,&r);
            num=getnum(r)-getnum(l-1);
            rate[i]=1.0*num/(r-l+1);
        }
        scanf("%lld",&k);
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(long long int i=1;i<=n;i++)
            dp[i][0]=dp[i-1][0]*(1.0-rate[i]);
        for(long long int i=1;i<=n;i++)
        {
            for(long long int j=1;j<=i;j++)
            {
                dp[i][j]+=dp[i-1][j-1]*rate[i]+dp[i-1][j]*(1.0-rate[i]);
            }
        }
        double ans=0.0;
        k=ceil(1.0*k/100.0*n);//ceil函数是求大于等于本身的最小整数
        for(long long int i=k;i<=n;i++)
            ans+=dp[n][i];
        printf("%.6f\n",ans);
    }
    return 0;
}


会津大学在线测评 AOJ Aizu Online Judge http://judge.u-aizu.ac.jp 注册 登录

会津大学在线测评 AOJ Aizu Online Judge http://judge.u-aizu.ac.jp 注册 登录 无法注册,无法登陆,怎么办,抓狂啊。 直接导致《挑战程序设计竞赛 算法和数...
  • mrcrack
  • mrcrack
  • 2017年09月20日 09:06
  • 557

AOJ 0033

链接:点击打开链接 题意:如图所示,十个带有数字的球从上到下依次落下,你可以自由控制挡板D,问是否可以使B,C两管的球都满足球上的数字由下到上依次递增 代码:#include #includ...
  • stay_accept
  • stay_accept
  • 2015年10月28日 13:17
  • 468

《挑战程序设计竞赛》2.5.1 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)

POJ2139http://poj.org/problem?id=2139题意奶牛们最近要拍电影了…… 1、若两个的奶牛一起工作则,他们相互的度(degrees)为; 2、若两只奶牛a、b不一起工...
  • thudaliangrx
  • thudaliangrx
  • 2015年12月30日 23:57
  • 839

AOJ 0118 Property Distribution 题解

题意大概就是判断区域的个数,同样的字符属于一个区域,问有多少个区域. 想起来以前一位老师给我讲的一道类似的题目...直接DFS求解,已经判断过的区域再用另一个字符填上即可. #include #i...
  • lrb2010
  • lrb2010
  • 2014年01月16日 13:53
  • 777

Aoj 0121 Seven Puzzle【bfs】

题目网址: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0121 http://acm.hust.edu.cn/vjudge/c...
  • liuke19950717
  • liuke19950717
  • 2016年03月05日 20:30
  • 450

noip2003 数字游戏

点击打开链接 #include #include #include #define INF 1
  • shenyuedong123
  • shenyuedong123
  • 2017年07月06日 21:39
  • 169

蓝桥杯:数字游戏

问题描述   栋栋正在和同学们玩一个数字游戏。   游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一...
  • lc0817
  • lc0817
  • 2015年05月13日 16:50
  • 1897

2016蓝桥杯历届试题——数字游戏

历届试题  数字游戏 问题描述   栋栋正在和同学们玩一个数字游戏。   游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要...
  • qq_21385857
  • qq_21385857
  • 2016年03月07日 15:09
  • 1346

AOJ0005 GCD and LCM【GCD+LCM】

GCD and LCM  Aizu - 0005 Write a program which computes the greatest common divisor (GCD) ...
  • tigerisland45
  • tigerisland45
  • 2018年01月06日 06:40
  • 145

[编程题] 数字游戏

小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2...
  • xll1314521
  • xll1314521
  • 2017年08月10日 21:34
  • 167
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:aoj 600 数字游戏
举报原因:
原因补充:

(最多只允许输入30个字)