zoukankan      html  css  js  c++  java
  • 题解 AT47 【パズルのお手伝い】

    传送门

    题意:

    很经典的八皇后问题,已知三个皇后的位置,求剩下五个皇后的位置,如果无解输出“(No Answer)

    思路:

    很显然dfs可以解决,暴力枚举每一行放的位置,通过已经放过的皇后的位置可以判断出很多不合法的位置,加上该剪枝即可

    代码实现:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    const int maxn = 10;
    int choose[maxn][maxn];
    int ans[maxn][maxn];
    int col[maxn];
    void updata (int x, int y) {
    	for (int k = 1; k <= 8; k++) choose[x][k]++, choose[k][y]++;
    	for (int k = 1; k + x <= 8 && k + y <= 8; k++) choose[x + k][y + k]++;
    	for (int k = 1; x - k >= 1 && y - k >= 1; k++) choose[x - k][y - k]++;
    	for (int k = 1; x - k >= 1 && y + k <= 8; k++) choose[x - k][y + k]++;
    	for (int k = 1; x + k <= 8 && y - k >= 1; k++) choose[x + k][y - k]++;
    	choose[x][y]--;
    }
    void Delete (int x, int y) {
    	for (int k = 1; k <= 8; k++) choose[x][k]--, choose[k][y]--;
    	for (int k = 1; k + x <= 8 && k + y <= 8; k++) choose[x + k][y + k]--;
    	for (int k = 1; x - k >= 1 && y - k >= 1; k++) choose[x - k][y - k]--;
    	for (int k = 1; x - k >= 1 && y + k <= 8; k++) choose[x - k][y + k]--;
    	for (int k = 1; x + k <= 8 && y - k >= 1; k++) choose[x + k][y - k]--;
    	choose[x][y]++;
    }
    bool judge = false;
    void dfs (int num) {
    	if (num == 9) {
    		judge = true;
    		return;
    	}
    	if (col[num]) dfs (num + 1);
    	if (judge == true) return;
    	for (int i = 1; i <= 8; i++) {
    		if (choose[num][i]) continue;
    		ans[num][i] = 1;
    		updata (num, i);
    		dfs (num + 1);
    		if (judge == true) return;
    		ans[num][i] = 0;
    		Delete (num, i);
    	}
    	if (judge == true) return;
    }
    int main () {
    	char c;
    	for (int i = 1; i <= 8; i++) {
    		for (int j = 1; j <= 8; j++) {
    			scanf (" %c", &c);
    			if (c == 'Q') {
    				if (choose[i][j] != 0) return puts("No Answer"), 0;
    				ans[i][j] = 1;
    				col[i] = 1;
    				updata (i, j);
    			}
    		}
    	}
    	dfs (1);
    	if (judge == true) {
    		for (int i = 1; i <= 8; i++) {
    			for (int j = 1; j <= 8; j++) {
    				if (ans[i][j] == 1) printf ("Q");
    				else printf (".");
    			}
    			puts("");
    		}
    	} else {
    		puts("No Answer");
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    将网址设为首页和添加到收藏夹(JS脚本)
    窗体居中一句话
    链接跳转JS
    工厂学习心得(三)Asp.net
    工厂模型学习心得(一)(ASP.Net)
    ubuntu终端快捷键
    Win7锐捷:无法找到网卡或系统未完成网卡初始化操作.请稍后再尝试认证
    Xming的使用
    在Windows上建立ssh服务器
    Windows XP循环启动
  • 原文地址:https://www.cnblogs.com/hzoi-liujiahui/p/14026698.html
Copyright © 2011-2022 走看看