蓝桥杯 基础练习 2n皇后问题 (简单dfs暴力+优化剪枝)

来源:互联网 发布:佟丽娅长相知乎 编辑:程序博客网 时间:2024/06/06 03:15
  基础练习 2n皇后问题  
时间限制:1.0s   内存限制:512.0MB
      
问题描述
  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入格式
  输入的第一行为一个整数n,表示棋盘的大小。
  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式
  输出一个整数,表示总共有多少种放法。
样例输入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
2
样例输入
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
0


/*思路:枚举  然后检测,回朔 总共有s=n*n个点   对于每个点 横坐标为s/now,纵坐标为s%n  水平方向  只需要检查0到s/now竖直方向  只需要检查0到s%now斜线方向 只需要检查左上和右上 能到达s就为一种方案 累加 */#include <iostream>#include <string.h>#include <cstdio>using namespace std;const int N=10;int map[N][N]; //0不能放 1可以放 2是黑皇后 3是白皇后 bool row[N][2],column[N][2];  //标记横列有没放 优化速度  0代表黑,1代表白 二维数组 int n,re;inline bool check(int x,int y,int v){//检查横竖和斜线 int i,a,b;//检查横 /*for(i=0;i<y;i++){if(map[x][i]==v)return false;} *///优化  if(row[x][v-2])   return false;    //检查竖 /*for(i=0;i<x;i++){if(map[i][y]==v)return false;} *///优化  if(column[y][v-2])    return false; //检查左上和右上  左上(-1,-1)*i  右上(-1,1)*i //检查左上 for(i=1;;i++){    a=x-i;b=y-i;if(a<0||b<0)  break;if(map[a][b]==v)return false;}//检查右上 for(i=1;;i++){    a=x-i;b=y+i;if(a<0||b>=n)  break;if(map[a][b]==v)return false;}return true;}void dfs(int now){int x=now/n;int y=now%n;//优化 到目前行位置前面每行行都有各一个黑白皇后for(int i=0;i<x;i++)if(!row[i][0]||!row[i][1])   return;    if(now==n*n){//结果检测  各有n个黑和白皇后/*没优化 n^2 int i,j,black=0,white=0;for(i=0;i<n;i++)for(j=0;j<n;j++){if(map[i][j]==2) black++; else if(map[i][j]==3) white++;}if(white==n&&black==n) */re++;return;}if(map[x][y]==1){     //当前格子可以放皇后     if(check(x,y,2))        {      row[x][0]=1;      //标记行列有人了       column[y][0]=1;      map[x][y]=2;      dfs(now+1);      map[x][y]=1;      row[x][0]=0;      column[y][0]=0;  }if(check(x,y,3)){row[x][1]=1;      //标记行列有人了       column[y][1]=1;map[x][y]=3;      dfs(now+1);      map[x][y]=1;      row[x][1]=0;            column[y][1]=0;}}dfs(now+1);      //不放 }int main(){    int i,j;    while(cin>>n){    re=0;        memset(row,0,sizeof(row));    memset(column,0,sizeof(column));        for(i=0;i<n;i++)     for(j=0;j<n;j++)     cin>>map[i][j];dfs(0);cout<<re<<endl;}return 0;}/*2n皇后问题01-01 17:012.390KBC++正确100280ms2.5MB评测详情2n皇后问题01-01 16:562.358KBC++运行超时62运行超时2.503MB评测详情2n皇后问题01-01 16:411.699KBC++运行超时50运行超时2.503MB评测详情*/


0 0
原创粉丝点击