zoukankan      html  css  js  c++  java
  • hdoj 2553 N皇后问题【回溯+打表】

    N皇后问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 11855    Accepted Submission(s): 5301


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

     

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

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

    Sample Input
    1
    8
    5
    0
     

    Sample Output
    1
    92
    10
    做题时需要注意以下几点:
        (1)本行所放的皇后位置不能与上一行同列
        (2)不能与上一行在主对角线上
        (3)不能与上一行在副对角线上
    判断是否在对角线上(此处不会  参考的刘汝佳编著的算法竞赛入门经典)
    根据下表判断主对角线 条件cur-a[cur]==j-a[j]可以判断主对角线
    0 1 2 3 4 5 6 7
    -1 0 1 2 3 4 5 6
    -2 -1 0 1 2 3 4 5
    -3 -2 -1 0 1 2 3 4
    -4 -3 -2 -1 0 1 2 3
    -5 -4 -3 -2 -1 0 1 2
    -6 -5 -4 -3 -2 -1 0 1
    -7 -6 -5 -4 -3 -2 -1 0

    格子(x,y)的y-x值标示了主对角线

    根据下表判断另一条对角线 条件cur+a[cur]==j+a[j]判断副对角线

    0 1 2 3 4 5 6 7
    1 2 3 4 5 6 7 8
    2 3 4 5 6 7 8 9
    3 4 5 6 7 8 9 10
    4 5 6 7 8 9 10 11
    5 6 7 8 9 10 11 12
    6 7 8 9 10 11 12 13
    7 8 9 10 11 12 13 14

    格子的(x,y)的x+y值标示了副对角线

    以上两图为棋盘的对角线标示

    附上AC代码:

    #include<stdio.h>
    #include<string.h>
    #define MAX 15
    int a[MAX];
    int s[MAX];
    int vis[MAX];
    int n,t,tot;
    void dfs(int cur)//cur代表行数
    {
    	int i,j;
    	if(cur==n)
    	{
    		tot++;//记录当前行数时符合题意的摆放个数 
    	}
    	else
    	{
    		for(i=0;i<n;i++)
    		{
    			int ok=1;
    			a[cur]=i;//尝试将皇后放在第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)//如果满足条件 
    			dfs(cur+1);//继续回溯 
    		}
    	}
    }
    int main()
    {
    	int m,j,i,k;
    	memset(a,0,sizeof(a));
    	memset(s,0,sizeof(s));
    	for(n=1;n<=10;n++)
    	{
    		tot=0;
    		dfs(0);
    		s[n]=tot;//打表记录对应行数时符合题意的个数 
    	}
    	while(scanf("%d",&t),t)
    	{
    		printf("%d
    ",s[t]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Samba 4.0 RC3 发布
    SymmetricDS 3.1.7 发布,数据同步和复制
    Express.js 3.0 发布,Node.js 的高性能封装
    GIFLIB 5.0.1 发布,C语言的GIF处理库
    jQuery UI 1.9.1 发布
    SVN Access Manager 0.5.5.14 发布 SVN 管理工具
    DynamicReports 3.0.3 发布 Java 报表工具
    HttpComponents HttpClient 4.2.2 GA 发布
    AppCan 2.0 正式发布,推移动应用云服务
    Ruby 2.0 的新功能已经冻结
  • 原文地址:https://www.cnblogs.com/tonghao/p/4607000.html
Copyright © 2011-2022 走看看