当前位置: 代码迷 >> 综合 >> [BZOJ]4807: 車 组合数学+高精度
  详细解决方案

[BZOJ]4807: 車 组合数学+高精度

热度:34   发布时间:2023-10-29 11:33:27.0

Description

众所周知,車是中国象棋中最厉害的一子之一,它能吃到同一行或同一列中的其他棋子。車跟車显然不能在一起打起来,于是rly一天又借来了许多许多的車在棋盘上摆了起来……他想知道,在N×M的矩形方格中摆最多个数的車使其互不吃到的情况下方案数有几种。但是,由于上次摆炮摆得实在太累,他为了偷懒,打算增加一个条件:对于任何一个車A,如果有其他一个車B在它的上面(車B行号小于車A),那么車A必须在車B的右边(車A列号大于車B)。棋子都是相同的。

题解

一开始看错题了TAT
原来是要摆最多的车。。、
所以就是C(max(n,m),min(n,m))就好了。。
然后这题数据还有问题。。
不仅是前50位,还要删去前导0QAQ
把我调死了

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1000005;
int n,m;
int pri[N],cnt=0;//质数表?
int tt[N];
bool ok[N];//这个数是不是质数
void In (int x,int y)
{if (ok[x]==true) {tt[x]+=y;return ;}for (int u=1;u<=cnt&&pri[u]*pri[u]<=x;u++){if (x==1) return;while (x%pri[u]==0){tt[pri[u]]+=y;x/=pri[u];}}if (ok[x]==true) {tt[x]+=y;return ;}if (x==1) return ;ok[x]=true;pri[++cnt]=x;tt[x]+=y;
}
int a[55],lalal;
void Add (int x)
{for (int u=1;u<=lalal;u++)a[u]=a[u]*x;for (int u=1;u<=lalal;u++){if (a[u]>10){a[u+1]+=(a[u]/10);a[u]%=10;}}lalal++;for (;lalal<=53;lalal++)if (a[lalal]>10){a[lalal+1]+=(a[lalal]/10);a[lalal]%=10;}else break;if (lalal>53 )lalal=53;a[54]=0;while (lalal>1&&a[lalal]==0) lalal--;
}
int mymin (int x,int y){
   return x<y?x:y;}
int main()
{memset(ok,false,sizeof(ok));memset(tt,0,sizeof(tt));scanf("%d%d",&n,&m);if (n>m) swap(n,m);cnt=0;for (int u=2;u<=n;u++)In(u,-1);for (int u=1;u<=n;u++)In(m-u+1,1);lalal=1;a[1]=1;for (int u=1;u<=cnt;u++){while (tt[pri[u]]!=0){Add(pri[u]);tt[pri[u]]--;}}for (int u=mymin(50,lalal);u>=1;u--)printf("%d",a[u]);return 0;
}