NYOJ 374 弹球II

链接:click here

题意:

游戏厅里有一种很常见的游戏机,里面有很多根管子有规律地排成许多行。小球从最上面掉下去,碰到管子会等概率地往管子左边或者右边的空隙掉下去。不过在最靠边的小球只会往一边掉(如图,灰色小球只可能掉到右边空隙)。现在已知共2*
n - 1行管子,第i行有Ai个管子,如果i是奇数,那么Ai等于m,如果i是偶数,Ai等于m-
1。小球从第1行第k个管子右边掉下去,要求小球从最后一行各个出口掉出来的概率。

输入
第一行是一个整数t(1≤t≤50),表示有t组测试数据。

每组数据第一行有两个整数n(1≤n≤100)和m(2≤m≤10),表示有2*n-1行管子,奇数行有m个管子,偶数行有m-1个管子。

第二行是一个整数k(1≤k≤m-1),表示小球从第1行第k个管子右边掉下去。

输出
输出m-1个小数,第i个数表示小球从最后一行第i个出口出来的概率。

每个小数保留小数点后六位,小数与小数之间用一个空格隔开。

样例输入
1
3 3
2
样例输出
0.375000 0.625000

这道题比较有趣,其实是一个概率模拟问题。

思路:

定义一个二维数组,map[i][j]表示第i行第j列从管子之间掉出来的概率,因为弹球是最上面放入的,所有我们想到只要弄清楚球从每一个管子掉下去,左边和右边的概率问题分别是多少,对数组里面的元素进行一个特别的操作,这里注意,因为管子每隔一行的数量要么别上一行多一个,要么比下一行多一个,因此分奇偶讨论:

输入三个数:n,m,k刚开始放入有:map[i][k]=1;

m为奇数: 有map[i][1]=map[i-1][1](最靠边只会往一边掉)+map[i-1][2]/2,map[i][m-1]=map[i-1][m1-1]/2+map[i-1][m];

m为偶数:有 map[i][1]=(map[i-1][1])/2,map[i][m]=(map[i-1][m-1])/2;  //处理边界,可以对照上图模仿

对于中间的数,我们知道球掉入的概率是上一行两边和的1/2。

因此,把整个过程仔细分析一遍,代码实现就不难了:

#include <math.h>
#include <queue>
#include <deque>
#include <vector>
#include <stack>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
const double eps = 1e-6;
const double Pi = acos(-1.0);
static const int inf= ~0U>>2;
static const int maxn =110;
double map[250][15];
int main()
{
    //freopen("11.txt","r",stdin);
    //freopen("22.txt","w",stdout);
    int n,m,m1,k,i,j;
    cin>>n;
    while(n--)
    {
        mem(map,0);
        cin>>m>>m1>>k;
        if(m1==2) puts("1.000000");
        else
        {
            map[1][k]=1;
            for(i=2; i<=m*2-1; i++)
            {
                if(!(i%2))
                {
                    map[i][1]=(map[i-1][1])/2,map[i][m1]=(map[i-1][m1-1])/2;  //处理边界
                    for(j=2; j<m1; j++)
                        map[i][j]=(map[i-1][j-1]+map[i-1][j])/2;
                }
                else
                {
                    map[i][1]=map[i-1][1]+map[i-1][2]/2,map[i][m1-1]=map[i-1][m1-1]/2+map[i-1][m1];  //处理边界,注意奇数排的时候边界的特殊情况
                    for(j=2; j<m1-1; j++)
                        map[i][j]=(map[i-1][j]+map[i-1][j+1])/2;
                }
            }
            cout.setf(ios::fixed);
            cout<<setprecision(6)<<map[i-1][1]<<endl;
            for(j=2; j<m1; j++)
                cout<<setprecision(6)<<map[i-1][j]<<endl;
        }
    }
    return 0;
}
时间: 2024-10-24 22:10:04

NYOJ 374 弹球II的相关文章

nyoj 弹球II(数学 模拟)

弹球II 时间限制:1000 ms  |  内存限制:65535 KB 描述 游戏厅里有一种很常见的游戏机,里面有很多根管子有规律地排成许多行.小球从最上面掉下去,碰到管子会等概率地往管子左边或者右边的空隙掉下去.不过在最靠边的小球只会往一边掉(如图,灰色小球只可能掉到右边空隙).现在已知共2 * n - 1行管子,第i行有Ai个管子,如果i是奇数,那么Ai等于m,如果i是偶数,Ai等于m - 1.小球从第1行第k个管子右边掉下去,要求小球从最后一行各个出口掉出来的概率. 输入 第一行是一个整数

NYOJ 469 擅长排列的小明 II

擅长排列的小明 II 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 小明十分聪明,而且十分擅长排列计算. 有一天小明心血来潮想考考你,他给了你一个正整数n,序列1,2,3,4,5......n满足以下情况的排列: 1.第一个数必须是1 2.相邻两个数之差不大于2 你的任务是给出排列的种数. 输入 多组数据.每组数据中输入一个正整数n(n<=55). 输出 输出种数. 样例输入 4 样例输出 4 来源 Ural 上传者 李文鑫 解题:俺找规律才找出来的,开始写了个暴

nyoj 623 A*B Problem II

A*B Problem II 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 ACM的C++同学有好多作业要做,最头痛莫过于线性代数了,因为每次做到矩阵相乘的时候,大量的乘法都会把他搞乱,所以他想请你写个程序帮他检验一下计算结果是否正确. 输入 有多组测试数据,每行给出一组m,n,k(0<m,n,k<=50).m,n,k表示两个矩阵的大小,其中: 矩阵A:m行n列. 矩阵B:n行k列. 接下来给出m*n个数表示矩阵A和n*k个数表示矩阵B,对于每个数s,0<

NYOJ 623 A*B ProblemII

A*B Problem II 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 ACM的C++同学有好多作业要做,最头痛莫过于线性代数了,因为每次做到矩阵相乘的时候,大量的乘法都会把他搞乱,所以他想请你写个程序帮他检验一下计算结果是否正确. 输入 有多组测试数据,每行给出一组m,n,k(0<m,n,k<=50).m,n,k表示两个矩阵的大小,其中: 矩阵A:m行n列. 矩阵B:n行k列. 接下来给出m*n个数表示矩阵A和n*k个数表示矩阵B,对于每个数s,0<

NYOJ 括号匹配系列2,5

本文出自:http://blog.csdn.net/svitter 括号匹配一:http://acm.nyist.net/JudgeOnline/problem.php?pid=2 括号匹配二:http://acm.nyist.net/JudgeOnline/problem.php?pid=15 之前被这个题目难住,现在看动态规划就顺便过来AC了它.结果发现当年被难住一点也不丢人.. 括号匹配一很简单,就是栈的应用,AC代码: //================================

各种曲线运动、弹球、笔记

// 绘制曲线 import java.awt.*; public class BallGame extends Frame { Image img = Toolkit.getDefaultToolkit().getImage("pingpang.jpg"); // 这种写法的问题就是开始时静态图像不会显示,需要最小化或最大化后才能显示 double x = 200; double y = 200; double degree = 0; public void paint(Graphi

NYOJ 取石子(八) 威佐夫博弈

取石子(八) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者.如果你胜,你第1次怎样取子? 输入 输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,

NYOJ 61 传纸条(一)

传纸条(一) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者

[LeetCode] 349 Intersection of Two Arrays &amp; 350 Intersection of Two Arrays II

这两道题都是求两个数组之间的重复元素,因此把它们放在一起. 原题地址: 349 Intersection of Two Arrays :https://leetcode.com/problems/intersection-of-two-arrays/description/ 350 Intersection of Two Arrays II:https://leetcode.com/problems/intersection-of-two-arrays-ii/description/ 题目&解法