题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1867
思路
用
f[i][j]
代表小球落到第
i
行第
f[i+1][j]+=12f[i][j],f[i+1][j+1]+=12f[i][j],(i,j)是钉子
f[i+2][j+1]+=f[i][j],(i,j)是空格
f[1][1]=1
然后写个恶心的分数结构体就行了,注意有个坑点:分数在通分时可能爆long long!
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 60
using namespace std;
typedef long long int LL;
LL gcd(LL a,LL b)
{
if(!b) return a;
return gcd(b,a%b);
}
struct Fraction
{
LL up,dn;
//Fraction(){ up=0,dn=1; } //!!!
Fraction(LL _up=0,LL _dn=1):up(_up),dn(_dn){}
void reduction()
{
LL t=gcd(up,dn);
up/=t,dn/=t;
}
void print()
{
cout<<up<<'/'<<dn;
}
}f[MAXN][MAXN];
Fraction operator*(Fraction a,Fraction b)
{
Fraction c=Fraction(a.up*b.up,a.dn*b.dn);
c.reduction();
return c;
}
Fraction operator+(Fraction a,Fraction b)
{
LL t=gcd(a.dn,b.dn);
Fraction c=Fraction(b.dn/t*a.up+a.dn/t*b.up,a.dn/t*b.dn);
c.reduction();
return c;
}
int n,m;
char map[MAXN][MAXN];
char getch()
{
char ch=getchar();
while(ch==' '||ch=='\n'||ch=='\r'||ch=='\t') ch=getchar();
return ch;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
map[i][j]=getch();
f[1][1]=Fraction(1,1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(map[i][j]=='*')
f[i+1][j]=f[i+1][j]+f[i][j]*Fraction(1,2),f[i+1][j+1]=f[i+1][j+1]+f[i][j]*Fraction(1,2);
else
f[i+2][j+1]=f[i+2][j+1]+f[i][j];
}
f[n+1][m+1].print();
return 0;
}