链接: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!(n−m)!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;
}