Description
某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。
他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)
Input
只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。
对于 30%的数据 n≤100,m≤100
对于 100%的数据 n≤2000,m≤2000
Output
输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。
注意答案可能很大。
Sample Input
1 1
Sample Output
12
题解Here!
这个题比较烦人。
分类讨论一下:
- 两个老师中间只站着一个女生。
这时$ ext{两老师+一女生}$应该看做一个整体。
对应答案就是:
$$A(n,n) imes A(n+1,1) imes A(2,2) imes A(n+2,m-1)$$
- 两个老师中间不止站一个女生。
这时中间一定有男生,于是随便插空就好了。
对应答案就是:
$$A(n,n) imes A(n+1,2) imes A(n+3,m)$$
然后题目中也说了,答案可能很大,所以。。。
高精度!
还是压了$5$位的高精度。。。
但是我上次不是立了个$flag$——不再写高精了吗?
嘿嘿,这次我是直接复制的高精模板哈哈哈!
不过我以后还是不写高精,只复制模板!
附代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define MAXN 10010 #define L 100000 using namespace std; int n,m; struct Bignum{ int len; long long val[MAXN]; void clean(){ len=0; memset(val,0,sizeof(val)); } void init(int k){ clean(); len=1; val[1]=k; } void write(){ printf("%lld",val[len]); for(int i=len-1;i>=1;i--)printf("%05lld",val[i]); printf(" "); } friend Bignum operator +(Bignum x,Bignum y){ Bignum s; s.clean(); s.len=max(x.len,y.len)+12; for(int i=1;i<=s.len;i++){ s.val[i]+=x.val[i]+y.val[i]; s.val[i+1]+=s.val[i]/L; s.val[i]%=L; } for(int i=1;i<=s.len;i++){ s.val[i+1]+=s.val[i]/L; s.val[i]%=L; } while(s.len&&!s.val[s.len])s.len--; return s; } friend Bignum operator *(Bignum x,Bignum y){ Bignum s; s.clean(); s.len=x.len+y.len+12; for(int i=1;i<=x.len;i++) for(int j=1;j<=y.len;j++){ s.val[i+j-1]+=x.val[i]*y.val[j]; s.val[i+j]+=s.val[i+j-1]/L; s.val[i+j-1]%=L; } for(int i=1;i<=s.len;i++){ s.val[i+1]+=s.val[i]/L; s.val[i]%=L; } while(s.len&&!s.val[s.len])s.len--; return s; } }ans; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } Bignum A(int n,int m){ Bignum s,x; s.clean(); if(m>n)return s; s.init(1); if(!m)return s; for(int i=n-m+1;i<=n;i++){ x.clean();x.init(i); s=s*x; } return s; } inline void solve(int n,int m){ ans=A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*A(n+1,1)*A(2,2)*A(m,1)*A(n+2,m-1); ans.write(); } int main(){ n=read();m=read(); solve(n,m); return 0; }