题目描述
某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)
输入格式
只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。
输出格式
仅一个非负整数,表示不同的排法个数。注意答案可能很大。
输入输出样例
输入 #1复制
1 1
输出 #1复制
12
说明/提示
对于 30% 的数据 n≤100,m≤100。
对于 100% 的数据 n≤2000,m≤2000。
代码实现:
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<cctype> #include<vector> #include<stack> #include<queue> #include<assert.h> using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 1e6 + 5; In ll rd() { ll res = 0; char c = getchar(), lst = ' '; while(!isdigit(c)) lst = c, c = getchar(); while(isdigit(c)) res = (res << 1) + (res << 3) + c - '0', c = getchar(); if(lst == '-') res = -res; return res; } In void wt(ll x) { if(x < 0) x = -x, putchar('-'); if(x >= 10) wt(x / 10); putchar(x % 10 + '0'); } In void FILE_IO() { #ifndef mrclr freopen("1.in", "r", stdin); freopen("ac.out", "w", stdout); #endif } int n, m; int num[maxn], l = 1; In void mul(int v) { l += 10; int d = 0; for(int i = 0; i < l; ++i) { num[i] = num[i] * v + d; d = num[i] / 10, num[i] %= 10; } while(l > 1 && !num[l - 1]) --l; } int main() { n = rd(), m = rd(); if(m > n + 3) {puts("0"); return 0;} num[0] = 1, l = 1; for(int i = 1; i <= n; ++i) mul(i); for(int i = n + 3 - m + 1; i <= n + 2; ++i) mul(i); mul(n + 1), mul(n * (n + 3) + 2 * m); for(int i = l - 1; i >= 0; --i) wt(num[i]); enter; return 0; }