HDU 2553-N皇后问题

本文探讨了在N*N的方格棋盘上放置N个皇后,使得它们不相互攻击的问题。通过DFS+回溯算法,实现了从低效到减少循环次数的优化过程,并最终提供了直接打表的方法来快速解决此问题。

Description

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

Sample Input

1

8

5

0

Sample Output

1

92

10

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553

DFS+回溯

低效:#include<stdio.h> const int MAXN=20; void search(int cur); int n,tot,A[MAXN]; int main() { freopen("in.txt","r",stdin); int result[11]; for(n=1;n<=10;n++){ tot=0; search(0); result[n]=tot; } while(scanf("%d",&n)&&n) printf("%d\n",result[n]); return 0; } void search(int cur) { int i,j; if(cur==n)tot++; else for(i=0;i<n;i++){ int ok=1; A[cur]=i; for(j=0;j<cur;j++){ if( A[cur]==A[j] ||cur-A[cur]==j-A[j] ||cur+A[cur]==j+A[j] ){ok=0;break;} } if(ok)search(cur+1); } }


改进,减少循环次数:#include<stdio.h> #include<memory.h> const int MAXN=30; void search(int cur); int n,tot,vis[3][MAXN]; int main() { // freopen("in.txt","r",stdin); int result[11]; for(n=1;n<=10;n++){ memset(vis,0,sizeof(vis)); tot=0; search(0); result[n]=tot; } while(scanf("%d",&n)&&n) printf("%d\n",result[n]); return 0; } void search(int cur) { if(cur==n)tot++; else for(int i=0;i<n;i++){ if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){ vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1; search(cur+1); vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; } } }


因为数据较小,可直接打表水过:#include<stdio.h> int main() { int n,a[11]={0,1,0,0,2,10,4,40,92,352,724}; while(scanf("%d",&n)&&n) printf("%d\n",a[n]); return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值