4563: [Haoi2016]放棋子
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 257 Solved: 161
[ Submit][ Status][ Discuss]
Description
给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子
的限制,求有多少种方案。
Input
第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例
Output
一个整数,即合法的方案数。
Sample Input
2
0 1
1 0
0 1
1 0
Sample Output
1
HINT
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
typedef long long LL;
const LL mo = 100000000;
struct data{
LL len,a[111];
data(){memset(a,0,sizeof(a)); len = 0;}
data operator + (const data &b)
{
data c;
int Len = max(len,b.len);
for (int i = 0; i < Len; i++)
{
c.a[i] += a[i] + b.a[i];
c.a[i+1] += c.a[i] / mo;
c.a[i] %= mo;
}
c.len = c.a[Len]?Len+1:Len;
return c;
}
data operator * (const LL &t)
{
data c;
for (int i = 0; i < len; i++)
{
c.a[i] += a[i] * t;
c.a[i+1] += c.a[i] / mo;
c.a[i] %= mo;
}
c.len = c.a[len]?len+1:len;
return c;
}
}A,B;
void Print(int x,int y)
{
if (y == 8)
{
printf("%d",x);
return;
}
Print(x / 10,y + 1);
printf("%d",x%10);
}
int n;
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n;
if (n == 1) {cout << 0; return 0;}
A.len = 1; B.len = 1; B.a[0] = 1;
for (int i = 3; i <= n; i++)
{
data C = (A + B)*(i-1);
A = B; B = C;
}
cout << B.a[B.len - 1];
for (int i = B.len - 2; i >= 0; i--) Print(B.a[i],1);
return 0;
}