• [codeup] 2046 八皇后


    题目描述

    会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
    对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
    给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。

    输入

    第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)

    输出

    输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。

    样例输入

    3
    6
    4
    25

    样例输出

    25713864
    17582463
    36824175

    思路

    八皇后问题的答案有92个,首先按照字典序生成这92个答案,然后根据下标查询即可。生成八皇后直接按行的顺序生成八个全排列,这八个全排列即为八行中每行皇后的位置,也就是列号,然后检查满足限制条件即可。

    简单的暴力生成版本:

    int count = 0;
    int n, p[maxn];
    bool hash_table[maxn] = {false};
    
    void generate_p(int index)
    {
    	if (index == n + 1) { // 判断全排列满足条件
    		bool flag = true;
    		for (int i = 1; i <= n; i++) {
    			for (int j = i + 1; j <= n; j++) {
    				if (abs(i - j) == abs(p[i] - p[j]))
    					flag = false;
    			}
    		}
    		if (flag)
    			count++;
    		return;
    	}
    	for (int x = 1; x <= n; x++) {
    		if (hash_table[x] == false) {
    			p[index] = x;
    			hash_table[x] = true;
    			generate_p(index + 1);
    			hash_table[x] = false;
    		}
    	}
    }
    

    由于某些全排列序列在前几个数出来时就可以判断是错误答案了,所以可以稍微优化以下代码,加上剪枝回溯的版本:

    int count = 0;
    int n, p[maxn];
    bool hash_table[maxn] = {false};
    
    void generate_p(int index)
    {
    	if (index == n + 1) {
    		count++;
    		return;
    	}
    	for (int x = 1; x <= n; x++) {
    		if (hash_table[x] == false) {
    			bool flag = true; // 剪枝
    			for (int pre = 1; pre < index; pre++) {
    				if (abs(index - pre) == abs(x - p[pre])) {
    					flag = false;
    					break;
    				}
    			}
    			if (flag == true) {
    				p[index] = x;
    				hash_table[x] = true;
    				generate_p(index + 1);
    				hash_table[x] = false;
    			}
    		}
    	}
    }
    

    代码

    #include <cstdio>
    #include <algorithm>
    
    const int maxn = 11;
    
    int n, p[maxn];
    bool hash_table[maxn] = {false};
    
    int count = 0;
    int solve[100] = {0};
    
    void generate_p(int index)
    {
    	if (index == n + 1) {
    		count++;
    		int tmp = 0;
    		for (int i = 1; i <= n; i++) {
    			tmp = tmp * 10 + p[i];
    		}
    		solve[count] = tmp;
    		return;
    	}
    	for (int x = 1; x <= n; x++) {
    		if (hash_table[x] == false) {
    			bool flag = true;
    			for (int pre = 1; pre < index; pre++) {
    				if (abs(index - pre) == abs(x - p[pre])) {
    					flag = false;
    					break;
    				}
    			}
    			if (flag == true) {
    				p[index] = x;
    				hash_table[x] = true;
    				generate_p(index + 1);
    				hash_table[x] = false;
    			}
    		}
    	}
    }
    
    int main()
    {
    	int m, t;
    
    	n = 8;
    	generate_p(1);
    
    	scanf("%d", &m);
    	while (m--) {
    		scanf("%d", &t);
    		printf("%d\n", solve[t]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Magento开发文档(一):Magento入门
    Magento开发文档(三):Magento控制器
    CSS 第一天
    iOS 关闭定时器
    thinkphp 5.0 Request使用
    iOS icon与启动图片
    数组
    PHP获取表单变量
    iOS ipa 包优化
    UIImage 渲染模式
  • 原文地址:https://www.cnblogs.com/trav/p/10356330.html
Copyright © 2020-2023  润新知