P3182 [HAOI2016]放棋子

来源:互联网 发布:淘宝秒杀是真的假的 编辑:程序博客网 时间:2024/05/21 10:47
                                      P3182 [HAOI2016]放棋子

题目描述

给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子的限制,求有多少种方案。

输入输出格式

输入格式:

 

第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例

 

输出格式:

 

一个整数,即合法的方案数。

 

输入输出样例

输入样例#1:
20 11 0
输出样例#1:
1

每一行和每一列的1是互补影响的
所以对于每一个n 方案数是一定的
如果我们把第i行的1 放到第i个位置
也就是 第i行的第i个位置不能放棋子
就是一个错排问题
2000的数据 要写高精
 1 /* 2     压位高精  3 */ 4 #include <cctype> 5 #include <cstdio> 6 #include <cstring> 7  8 const int p=4; 9 const int MAXN=5010;10 const int mod=10000;11 const int MAXM=10010;12 13 int n,ans,tot;14 15 int map[MAXN][MAXN],a[MAXM],b[MAXM],c[MAXM];16 17 inline void read(int&x) {18     int f=1;register char c=getchar();19     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());20     for(;isdigit(c);x=x*10+c-48,c=getchar());21     x=x*f;22 }23 24 inline void mul(int x) {25     c[0]=b[0]+1;26     for(int i=1;i<=c[0];++i) c[i]=x*b[i];27     for(int i=1;i<=c[0];++i) {28         if(i==c[0]&&c[i]>mod) ++c[0];29         c[i+1]+=c[i]/mod;30         c[i]%=mod;31     }32     while(c[0]&&!c[c[0]]) --c[0];33     for(int i=1;i<=c[0];++i) b[i]=c[i];34     b[0]=c[0];35     memset(c,0,sizeof c);36 }37 38 inline void plus() {39     c[0]=b[0]+1;40     for(int i=1;i<=c[0];++i) {41         c[i]+=a[i]+b[i];42         c[i+1]+=c[i]/mod;43         c[i]%=mod;44     } 45     while(c[0]>0&&!c[c[0]]) --c[0];46     for(int i=1;i<=b[0];++i) a[i]=b[i];47     a[0]=b[0];48     for(int i=1;i<=c[0];++i) b[i]=c[i];49     b[0]=c[0];50     memset(c,0,sizeof c);51 }52 53 int hh() {54     freopen("chess_2016.in","r",stdin);55     freopen("chess_2016.out","w",stdout);56     read(n);57     for(int i=1;i<=n;++i)58       for(int j=1;j<=n;++j)59           read(map[i][j]);60     a[0]=1;b[0]=1;61     a[a[0]]=1;b[b[0]]=2;62     if(n==2) {printf("1\n");return 0;}63     if(n==3) {printf("2\n");return 0;}64     for(int i=4;i<=n;++i) plus(),mul(i-1);65     printf("%d",b[b[0]]);66     for(int i=b[0]-1;i>=1;--i) printf("%0*d",p,b[i]);67     return 0;68 }69 70 int sb=hh();71 int main(int argc,char**argv) {;}
代码

 

原创粉丝点击