zoukankan      html  css  js  c++  java
  • noi99钉子和小球 解题报告

    题目叙述

    钉子和小球
    Time Limit: 1000MS Memory Limit: 10000K

    题目描述

    有一个三角形木板,竖直立放,上面钉着n(n + 1) / 2颗钉子,还有(n + 1)个格子(当n = 5时如图1)。每颗钉子和周围的钉子的距离都等于d,每个格子的宽度也都等于d,且除了最左端和最右端的格子外每个格子都正对着最下面一排钉子的间隙。 让一个直径略小于d的小球中心正对着最上面的钉子在板上自由滚落,小球每碰到一个钉子都可能落向左边或右边(概率各1/2),且球的中心还会正对着下一颗将要碰上的钉子。例如图2就是小球一条可能的路径。 我们知道小球落在第i个格子中的概率pi=,其中i为格子的编号,从左至右依次为0, 1, ..., n。现在的问题是计算拔掉某些钉子后,小球落在编号为m的格子中的概率pm。假定最下面一排钉子不会被拔掉。例如图3是某些钉子被拔掉后小球一条可能的路径。

    输入描述

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

    输出描述

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

    样例输入

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

    样例输出

    7/16

    这题真的做的人吐血.....本来DP已经写的够小心了,还要弄个高精才过的了...唉呀,不管了

    只要注意细节,就可以通过.....

    1.题目给出的是钉子的位置,但是我们要用到的空格,切每次球通过的路径是钉子间的空隙,所以要相应的处理下。本人采用的是map[i,j]储存的是(i,j)位置钉子的情况,f[i-1,j]储存的是钉子(i,j)的通过的球的情况。

    2.动态方程如下:

     f[i+1,j]:=f[i,j]+f[i+1,j];f[i+1,j+1]:=f[i,j]+f[i+1,j+1]; (if map[i,j]='*')

       f[i+2,j+1]:=f[i,j]*4+f[i+2,j+1];(if map[i,j]='.')

    3.记得加高精!

    代码如下:

      1 const acc=10000;
      2 type
      3     arra=record
      4                da:array[0..30]of longint;
      5                l:longint;
      6     end;
      7 var i,j,n,m,q:longint;
      8     map:array[0..50,0..50]of char;
      9     f:array[0..60,0..60]of arra;
     10     ch:char;
     11     fm,t,z:arra;
     12 function add(a,b:arra):arra;
     13 var
     14    c:arra;i:longint;
     15 begin
     16      fillchar(c,sizeof(c),0);
     17      if a.l>b.l then c.l:=a.l else c.l:=b.l;
     18      for i:=1 to c.l do
     19          begin
     20               c.da[i]:=c.da[i]+a.da[i]+b.da[i];
     21               if c.da[i]>=acc then
     22                  begin
     23                       inc(c.da[i+1]);
     24                       c.da[i]:=c.da[i] mod acc;
     25                  end;
     26          end;
     27      if c.da[c.l+1]>0 then inc(c.l);
     28      add:=c;
     29 end;
     30 procedure mult2(var a:arra);
     31 var i,k:longint;b:arra;
     32 begin
     33      k:=0;
     34      fillchar(b,sizeof(b),0);
     35      b.l:=a.l;
     36      for i:=1 to a.l do
     37          begin
     38               b.da[i]:=b.da[i]+a.da[i]*2;
     39               if b.da[i]>=acc then
     40                  begin
     41                       b.da[i]:=b.da[i] mod acc;
     42                       inc(b.da[i+1]);
     43                  end;
     44          end;
     45      if b.da[b.l+1]<>0 then inc(b.l);
     46      a:=b;
     47 end;
     48 procedure divid2(var a:arra);
     49 var i,k,t:longint;b:arra;
     50 begin
     51      k:=0;
     52      fillchar(b,sizeof(b),0);
     53      b.l:=a.l;
     54      for i:= a.l downto 1 do
     55          begin
     56               k:=k*acc+a.da[i];
     57               if k>=2 then
     58                  begin
     59                       t:=k shr 1;
     60                       b.da[i]:=t;
     61                       k:=k-(t shl 1);
     62                  end;
     63          end;
     64      a:=b;
     65      while (a.da[a.l]=0)and(a.l>1do dec(a.l);
     66 end;
     67 procedure print(a:arra);
     68 var i:longint;s:string;
     69 begin
     70      write(a.da[a.l]);
     71      for i:=a.l-1 downto 1 do
     72          begin
     73               str(a.da[i]+acc,s);
     74               delete(s,1,1);
     75               write(s);
     76          end;
     77 end;
     78 begin
     79      
     80      readln(n,m);
     81      fillchar(f,sizeof(f),0);
     82      f[0,1].da[1]:=1;f[0,1].l:=1;
     83      for i:=1 to n do
     84          begin
     85               for j:=1 to i do
     86                   begin
     87                        read(ch);
     88                        while (ch<>'*')and(ch<>'.'do read(ch);
     89                        map[i,j]:=ch;
     90                   end;
     91               readln;
     92          end;
     93      for i:=0 to n-1 do
     94          begin
     95               for j:=1 to i+1 do
     96                   begin
     97                        if map[i+1,j]='*' then
     98                           begin
     99                                f[i+1,j]:=add(f[i,j],f[i+1,j]);
    100                                f[i+1,j+1]:=add(f[i,j],f[i+1,j+1]);
    101                           end
    102                        else
    103                            begin
    104                                 z:=add(f[i,j],f[i,j]);
    105                                 z:=add(z,z);
    106                                 f[i+2,j+1]:=add(z,f[i+2,j+1]);
    107                            end;
    108                   end;
    109          end;
    110     t:=f[n,m+1];
    111     if (t.l=1)and(t.da[1]=0then writeln('0/1')
    112     else
    113         begin
    114              q:=n;
    115              while not(odd(t.da[1])) and not((t.l=0)and(t.da[1]=0)) do
    116                    begin
    117                         divid2(t);
    118                         dec(q);
    119                    end;
    120              fillchar(fm,sizeof(fm),0);
    121              fm.da[1]:=1;fm.l:=1;
    122              for i:=1 to q do mult2(fm);
    123              print(t);write('/');print(fm);writeln;
    124         end;
    125 end.
  • 相关阅读:
    DateUtils
    Java静态绑定与动态绑定
    Mysql中实现递归查询
    架构一、核心概念
    Spring cron 表达式
    MySql点点滴滴(一)之可视化工具介绍
    java中注解的使用与实例
    3、第一个Python程序
    CSS命名
    如何在Notepad++ 中成功地安装Emmet 插件
  • 原文地址:https://www.cnblogs.com/waterfalleagle/p/1599991.html
Copyright © 2011-2022 走看看