[BZOJ 4563]放棋子

本文介绍了一道BZOJ4563放棋子的题目,该题要求在N*N矩阵中放置N枚棋子,矩阵中每行存在一个障碍物且任意两个障碍物不在同一行也不在同一列。文章提供了一种高效的解题思路,通过全错位排列的方法求得合法的放置方案数。
摘要由CSDN通过智能技术生成

[BZOJ 4563]放棋子

题目

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

INPUT

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

OUTPUT

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

SAMPLE

INPUT

2
0 1
1 0

OUTPUT

1

解题报告

一道读入都不用打完的题= =

只用读入$n$就好了QAQ

全错位排列往上一打,加个高精就好了QAQ

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 struct bign{
 6     int a[1005],len;
 7     bign():len(1){memset(a,0,sizeof(a));}
 8     bign(const char *s){*this=s;}
 9     bign(const int &x){*this=x;}
10     inline void operator=(const char *s){
11         len=strlen(s);
12         for(int i=0;i<len;++i)
13             a[i]=s[len-i-1]-'0';
14     }
15     inline void operator=(const int &x){
16         char s[1005];
17         memset(s,0,sizeof(s));
18         sprintf(s,"%d",x);
19         *this=s;
20     }
21     inline void clear(){while(len>1&&!a[len-1])--len;}
22     inline bign operator+(const bign &x){
23         bign ret;
24         ret.len=max(len,x.len)+1;
25         int jw(0);
26         for(int i=0;i<len;++i){
27             ret.a[i]=a[i]+x.a[i]+jw;
28             jw=ret.a[i]/10;
29             ret.a[i]%=10;
30         }
31         if(jw)
32             ret.a[len++]=jw;
33         ret.clear();
34         return ret;
35     }
36     inline void operator+=(const bign &x){*this=*this+x;}
37     inline bign operator-(const bign &x){
38         bign ret;
39         ret=*this;
40         for(int i=0;i<len;++i){
41             if(ret.a[i]<x.a[i])
42                 ret.a[i]+=10,--ret.a[i+1];
43             ret.a[i]=ret.a[i]-x.a[i];
44         }
45         ret.clear();
46         return ret;
47     }
48     inline void operator-=(const bign &x){*this=*this-x;}
49     inline bign operator-(const int &x){
50         bign tmp(x);
51         return *this-tmp;
52     }
53     inline void operator-=(const int &x){*this=*this-x;}
54     inline bign operator*(const bign &x){
55         bign ret;
56         ret.len=len+x.len+1;
57         int jw;
58         for(int i=0;i<len;++i){
59             jw=0;
60             for(int j=0;j<x.len;++j){
61                 ret.a[i+j]+=a[i]*x.a[j]+jw;
62                 jw=ret.a[i+j]/10;
63                 ret.a[i+j]%=10;
64             }
65             ret.a[i+x.len]+=jw;
66         }
67         ret.clear();
68         return ret;
69     }
70     inline void operator*=(const bign &x){*this=*this*x;}
71     inline bign operator*(const int &x){
72         bign tmp(x);
73         return *this*tmp;
74     }
75     inline void operator*=(const int &x){*this=*this*x;}
76     inline void print(){
77         for(int i=len-1;i>=0;--i)
78             printf("%d",a[i]);
79     }
80 }f[205];
81 int n;
82 int main(){
83     scanf("%d",&n);
84     f[0]=1;
85     f[1]=0;
86     for(int i=2;i<=n;++i)
87         f[i]=(f[i-1]+f[i-2])*(i-1);
88     f[n].print();
89 }
View Code

 

转载于:https://www.cnblogs.com/hzoi-mafia/p/7669817.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值