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;
}