[NOI1999] 钉子和小球

2023-10-31 11:59
文章标签 小球 noi1999 钉子

本文主要是介绍[NOI1999] 钉子和小球,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

有一个三角形木板,竖直立放,上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1)。每颗钉子和周围的钉子的距离都等于d,每个格子的宽度也都等于d,且除了最左端和最右端的格子外每个格子都正对着最下面一排钉子的间隙。

让一个直径略小于d的小球中心正对着最上面的钉子在板上自由滚落,小球每碰到一个钉子都可能落向左边或右边(概率各1/2),且球的中心还会正对着下一颗将要碰上的钉子。例如图2就是小球一条可能的路径。

我们知道小球落在第i个格子中的概率pi= Image:Ball1.gif ,其中i为格子的编号,从左至右依次为0,1,...,n。

现在的问题是计算拔掉某些钉子后,小球落在编号为m的格子中的概率pm。假定最下面一排钉子不会被拔掉。例如图3是某些钉子被拔掉后小球一条可能的路径。

Image:Ball2.gif

输入

第1行为整数n(2<=n<=50)和m(0<=m<=n)。以下n行依次为木板上从上至下n行钉子的信息,每行中‘*’表示钉子还在,‘.’表示钉子被拔去,注意在这n行中空格符可能出现在任何位置。

输出

仅一行,是一个既约分数(0写成0/1),为小球落在编号为m的格子中的概pm。既约分数的定义:A/B是既约分数,当且仅当A、B为正整数且A和B没有大于1的公因子。

样例输入

5 2** .* * ** . * *
* * * * *

样例输出

7/16
***********************************************************************************
一道简单的递推题,在做事特别注意的是数据类型的处理long long;
**********************************************************************************
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #define LL  long long
 6 using namespace std;
 7 LL  n,m,i,j;
 8 LL  dp[1000][1000],temp;//变量常量说明
 9 char a[1000][1000];//变量常量说明
10 char ch;//变量常量说明
11 LL zide(LL  a,LL b)//求最大公约数的函数
12     {
13         if(b==0)
14             return a;
15         return zide(b,a%b);
16     }
17 void init()//初始化函数
18 {
19    cin>>n>>m;
20    for(i=0;i<n;i++)
21      {
22          j=0;
23          while(1)//输入有技巧
24          {
25              ch=getchar();
26              if(ch=='*'||ch=='.')
27                 a[i][j++]=ch;
28               if(j>i)break;
29          }
30      }
31 
32 
33 }
34 void  sovle()//递推函数
35 {
36    memset(dp,0,sizeof(dp));
37    dp[0][0]=(LL)((LL)1<<(LL)n);//注意此此处要强制转换LL
38    //cout<<dp[0][0]<<endl;
39    for(i=1;i<=n;i++)
40     for(j=0;j<i;j++)
41      {
42          if(a[i-1][j]=='*')//如果有钉子,下面的两个钉子各分这个钉子的一半小球
43            {
44                temp=dp[i-1][j]>>1;
45               // cout<<temp<<endl;
46                dp[i][j]+=temp;
47                dp[i][j+1]+=temp;
48                //cout<<dp[i][j]<<' '<<dp[i][j+1]<<endl;
49            }
50         else
51           if(a[i-1][j]=='.')//如果无钉子,则直接落到隔一行正对的钉子上
52            dp[i+1][j+1]+=dp[i-1][j];
53            //cout<<dp[i+1][j+1]<<endl;
54      }
55      LL  d=zide(dp[0][0],dp[n][m]);
56             //cout<<d<<endl;
57         cout<<dp[n][m]/d<<'/'<<dp[0][0]/d<<endl;//输出结果
58 
59 }
60 
61 int main()
62 {
63     freopen("ball.in","r",stdin);
64    freopen("ball.out","w",stdout);
65 
66   init();
67   sovle();
68      return 0;
69 }
View Code

转载于:https://www.cnblogs.com/sdau--codeants/p/3151000.html

这篇关于[NOI1999] 钉子和小球的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315195

相关文章

12个小球 梅氏砝码问题

1. 12个小球,其中有一个是坏球。有一架天平。需要你用最少的称次数来确定哪个小球是坏的并且它到底是轻还是重。 来源:http://blog.csdn.net/pongba/article/details/2544933 这个问题是一道流传已久的智力题。网络上也有很多讲解,还有泛化到N个球的情况下的严格证明。也有零星的一些地方提到从信息论的角度来看待最优解法。本来我一直认

Android 自定义View控件,实现跟随手指触摸移动的小球

Android UI组件是通过继承View类,然后绘制内容,比如ImageView,TextView等组件都是继承View类。 当Android系统提供的组件功能不能满足需求时,可以通过继承View类重写一个或多个方法,派生自定义的组件,View类常用重写方法: 1.构造器:View子类最基本的重写方法 protected voidonDraw(Canvas canvas) public

Android 自定义控件 loding小球

以下为参照博客    http://blog.csdn.net/guimianhao9833/article/details/74858472  首先看下效果图: 步骤: 1.继承view,并需要三个构造函数。 public MyView(Context context) {//注意不要默认实现,记得修改。 this(context, n

面试or笔试6——小球下落距离

小东和三个朋友一起在楼上抛小球,他们站在楼房的不同层,假设小东站的楼层距离地面N米,球从他手里自由落下,每次落地后反跳回上次下落高度的一半,并以此类推知道全部落到地面不跳,求4个小球一共经过了多少米?(数字都为整数) 给定四个整数A,B,C,D,请返回所求结果。 测试样例: 100,90,80,70 返回:1020 根据极限的思想可直接求得单个小球的下落距离之和为3*N c

移动的小球

VB中有个例子为“移动的小球”,下面有两种编码。一种可以运行成功,另一种不能运行成功。 这个代码不能运行成功。 这个代码可以运行成功。 按照逻辑来来说,这两种代码,均可运行成功。但是第一种并不是想象的那样。原因不明,哪位高手能解读一下?

Algorithm学习笔记 --- 小球下落问题(二叉树解法)

有一颗二叉树,最大深度为D,且所有的叶子深度都相同。所有的结点从上到下从左到右编号为 1,2,3,4,....,2^D-1.在结点1处放一个小球,它会往下落。每个结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,它的状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,知道走到叶子结点。 一些小球从结点1处开始下落,最后一个小球会落到哪里呢?输入叶子深

Algorithm学习笔记 --- 小球移动问题

此题用链表更加的方便一些。 你有一些小球,从左到右依次编号为1,2,3,…,n, 你可以执行两种指令。其中A X Y表示把小球X移动到小球Y左边,B X Y表示把小球X移动到小球Y右边。指令保证合法,即X不等于Y。 输入    小球个数n。指令条数m和m条指令,注意,1≤n≤500000,0≤m≤100000。 输出    从左到右输出最后的小球序列。

Android仿QQ邮箱下拉刷新动画(三个小球围绕中心转动)

仿QQ邮箱下拉刷新动画(三个小球围绕中心转动) 该动画的实现主要借鉴了海龙的博客- 两个小球不停的绕中心旋转的进度条 ,在此感谢下。 1 首先上图(折腾了好久才把gif给搞了上去) 2 分析 2.1 当我们看到一个动画,首先需要对动画的效果进行分析,而不是盲目的进行开发 2.2 动画的分解(先需要关注一个小球的效果,避免其他干扰) 2.2.1 平移动画:把中心点的横坐标当作坐

模仿搜狗浏览器加载小球

用过android 搜狗浏览器客户端的用户就知道,每次加载页面就会有个下落的加载小球,为了实现它,我上网查资料,在泡在网上的日子上面找到了相关资料,但是没有具体详细的教程,所以我就分享一下我的思路。 先上一张效果图(由于博主一直没有找到怎么在博客中播放gif,所以就来一张静态的吧,要想看具体效果,清下载源码编译): 具体思路: 1、继承View自写控件,并获取控件长宽。 2、根据已经获

【小球下落反弹】小球自由落下,每次落地后反跳回原高度的一半

一小球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? 使用C语言实现,具体代码: #include<stdio.h>int main(){float sn=100.0,hn=sn/2;for(int n=2;n<=10;n++){sn=sn+2*hn;hn=hn/2;}printf("共经过%f米\n第10次反弹%f米高",