棋盘问题1
问题描述
在n×n(n≤20)
的方格棋盘上放置n个车(可以攻击所在行、列),求使它们不能互相攻击的方案总数。
输入格式
一行,若干个1到20之间的整数。
输出格式
若干行,对于输入的每个整数,输出其方案数。
样例输入
3 2
样例输出
6
2
限制与约定
时间限制:1s
空间限制:128MB
#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long f[1<<20]; int main() { int n; while(scanf("%d",&n)==1) { memset(f,0,sizeof(f)); f[0]=1; for(long long i=1;i<=(1<<n);i++) for(long long t=i;t>0;t-=t&-t) f[i]+=f[i&~(t&-t)]; cout<<f[(1<<n)-1]<<endl; } return 0; }
棋盘问题2
问题描述
在 n×n(n≤20)
的方格棋盘上放置n 个车(可以攻击所在行、列),某些格子不能放,求使它们不能互相攻击的方案总数。
输入格式
给你一个n和m,分别表示棋盘的大小,不能放的格子总数。接下来是m行坐标,表示不能放置的位子。
输出格式
符合条件的方案总数。
输入样例1
3 2
1 2
2 3
输出样例1
3
输入样例2
4 1
1 1
输出样例2
18
限制与约定
时间限制:1s
空间限制:128MB
#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long f[1<<20],s[25]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(f,0,sizeof(f)); memset(s,0,sizeof(s)); for(int i=0,a,b;i<m;i++) { cin>>a>>b; s[a]+=1<<(b-1); } f[0]=1; for(long long i=1;i<=(1<<n);i++) { int num=0; for(long long t=i;t>0;t-=t&-t) num++; for(long long t=i;t>0;t-=t&-t) if(!(s[num]&(t&-t))) f[i]+=f[i&~(t&-t)]; } cout<<f[(1<<n)-1]<<endl; } return 0; }
棋盘问题3
问题描述
给出一个n×m
的棋盘(n、m≤80,n×m≤80
),要在棋盘上放k(k≤20)个棋子, 使得任意两个棋子不相邻(相邻指上下左右四个方向)。求可以放置的总的方案数。
输入格式
一行三个整数n,m,k,表示棋盘大小为n行m列,棋盘上放置k个棋子。
输出格式
一个整数表示方案数。
输入样例1
3 3 2
输出样例1
24
输入样例2
2 2 2
输出样例2
2
输入样例3
20 1 2
输出样例3
171
限制与约定
时间限制:1s
空间限制:128MB