错排模板
有一个糊涂人,写了n封信和n个信封,到了邮寄的时候,把所有的信都装错了信封。求装错信封可能的种类数。
输入格式
每行输入一个正整数n,表示一种情况。(n<=20)
输出格式
输出相应的答案。
输入样例
1
3
4
输出样例
0
2
9
一共有两种模板
一种是预处理一下,类似于dp
一种是运用递归(上面也差不多)
这里运用递归
如果两封信互相错放则剩下n-2封信错排
如果不是,剩下n-1封信错排
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const ull MOD=0x3f3f3f3f3f;
const double PI=3.1415926;
ull alg(int n)
{
if(n==1)
return 0;
if(n==2 )
return 1;
return (n-1)*(alg(n-1)+alg(n-2));
}
int main()
{
int n;
while(cin>>n)
cout<<alg(n)<<endl;
return 0;
}
排列组合类
在一个N*M的棋盘中,存在多少种方式使得两个皇后可以互相攻击。
输入格式
输入有若干行,每行两个数N,M(1<=N,M<=10^6)
输出格式
对于每组测试数据输出一行表示答案
输入样例
1 2
2 2
2 3
输出样例
2
12
26
一条直线上才能攻击,一共有(n*(n-1))
水平竖直都知道是多少种
斜线呢一共为1 2 3 ……n n n n n n ……3 2 1(中间有连续的m-n+1个n)(保证m>n)
即列大于行(行列地位相同,那个大都可以,知道就行)
1-->n-1的部分计算后*2(左右对称)再*2(斜线翻转)
n的部分*(m-1+1)*2即可
累加
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const ull MOD=0x3f3f3f3f3f;
const double PI=3.1415926;
//double times[8]= {0.1,0.075,0.05,0.03,0.015,0.01};
//f-1就好了
int main()
{
ull m,n;
while(cin>>n>>m)
{
ull i,j,k;
if(n>m)
swap(m,n);
ull sum=0,sum1,sum2=0;
sum1=m*n*(m+n-2);
for(i=1; i<=n-1; i++)
sum2+=i*(i-1)*2*2;
for(i=1; i<=m-n+1; i++)
sum2+=n*(n-1)*2;
cout<<sum1+sum2<<endl;
}
return 0;
}