牛客网 - 井字棋 C++

链接:https://ac.nowcoder.com/acm/contest/9680/A
来源:牛客网

题目描述
现在有一个 3*3 的棋盘,上面只有一些黑棋(至多有六个黑棋)。 等概率随机地往棋盘中放入三个白棋,求这三个白棋刚好属于同一行或同一列或同一对角线的概率。
输入描述:
每组测试数据由三行组成,每行由一个长度为 3 的字符串组成,描述一个棋盘的情况。“X"代表黑棋,”."代表此位置没有棋。保证字符串仅包含以上两种字符。
输出描述:
假设概率化为最简分式为 a/b,输出一行由空格隔开的两个整数 a b 代表答案。特别地,如果概率为 0,只输出一行一个整数 0 即可。
示例1
输入

XXX
XXX
...

输出

1 1

解题思路:
假设黑棋x个,没有棋子的位置有n= 9-x个
符 合 条 件 的 组 合 ( 三 个 白 棋 刚 好 属 于 同 一 行 或 同 一 列 或 同 一 对 角 线 ) 所 有 可 能 出 现 的 情 况 ( C n 3 ) \frac{符合条件的组合(三个白棋刚好属于同一行或同一列或同一对角线) }{ 所有可能出现的情况( \mathbf{C}_n^3)} (Cn3)(线)

排列与组合公式:
C ( n , m ) = C n m = n ! m ! ( n − m ) ! C(n,m) = \mathbf{C}_n^m = \frac{n!} {m! (n-m)!} C(n,m)=Cnm=m!(nm)!n!

#include<iostream>  
using namespace std;  
//最大公约数
int gcd(int a, int b)  
{  
    if(a % b == 0)  
    {  
        return b;  
    }  
    return gcd(b, a % b);  
}  
int jiecheng(int n)  //阶乘
{  
    int sum = 1;  
    for(int i = 1; i <= n; i++)  
    {  
        sum = sum * i;  
    }  
    return sum;  
}  
int C(int x,int y)  //Cn3排列组合
{  
    return jiecheng(x)/jiecheng(x-y)/jiecheng(y);  
}  
int main()   
{  
    char a[3][3] ;  
    int x = 0;  //黑棋
    for(int i = 0; i < 3; i++)   
    {  
        for(int j = 0; j < 3; j++)   
        {  
            cin>>a[i][j];  
            if(a[i][j] == 'X')  
            {  
                x++;  
            }  
        }  
    }  
    int ans = 0;  //满足条件的情况
    //同一行
    if(a[0][0] == '.' && a[0][1] == '.' && a[0][2] == '.')ans++;  
    if(a[1][0] == '.' && a[1][1] == '.' && a[1][2] == '.')ans++;  
    if(a[2][0] == '.' && a[2][1] == '.' && a[2][2] == '.')ans++;  
    //同一列
    if(a[0][0] == '.' && a[1][0] == '.' && a[2][0] == '.')ans++;  
    if(a[0][1] == '.' && a[1][1] == '.' && a[2][1] == '.')ans++;  
    if(a[0][2] == '.' && a[1][2] == '.' && a[2][2] == '.')ans++;  
    //对角线
    if(a[0][0] == '.' && a[1][1] == '.' && a[2][2] == '.')ans++;  
    if(a[0][2] == '.' && a[1][1] == '.' && a[2][0] == '.')ans++;  
      
    int temp = 9 - x;  //没有棋子
    int fenmu = C(temp, 3);  // 所有可能出现的情况
      
    if(ans == 0)  
    {  
        cout<<0<<endl;  
    }  
    else  
    {  //化简为最简分式
        cout<<ans/gcd(ans, fenmu)<<" "<<fenmu/gcd(ans, fenmu)<<endl;  
    }  
      
  
    return 0;  
      
}  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sail Jamie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值