首页 > 其他分享 >题解 ARC001C【パズルのお手伝い】

题解 ARC001C【パズルのお手伝い】

时间:2022-11-15 17:45:55浏览次数:97  
标签:fzx ARC001C 题解 dfs fh 皇后 fyx fl

posted on 2021-01-11 18:20:37 | under 题解 | source

前言

这道题八皇后很像,可以做完八皇后再来做这道题。如果你 \(\color{white}\colorbox{red}{WA}\) 了,请检查你有没有换行,有没有混淆大小写。

题意简述

一个 \(8\times 8\) 的棋盘,要摆 \(8\) 个皇后,要求每位皇后所在的 \(2\) 条直线和 \(2\) 条斜线上不能摆另一个皇后。现在已经摆了 \(3\) 个,如果有解,输出解,否则输出No Answer

思路

很明显,这是一道dfs的题目,我们要一行行的dfs

我们开 \(4\) 个bool数组 \(fh,fl,fzx,fyx\) (行、列、左斜、右斜),对于点 \((x,y)\) 来说,它占领了第 \(fh_x\) 行,第 \(fl_y\) 列,第 \(fzx_{x+y-1}\) 条左斜线,第 \(fyx_{x-y+8}\) 条右斜线。这个稍微画个图推个规律就能知道。如果fh[x]||fl[y]||fzx[x+y-1]||fyx[x-y+8]为真,说明这个格子摆不了皇后了,继续枚举下一个点。

注意,如果这一行已经摆了皇后了,直接搜下一行,这一行就不用管了。

无解有 \(2\) 种情况:

  1. 输入的棋盘上有两个同一条直线或斜线上的皇后。
  2. dfs搜不到解。

对于情况一,我们只需在输入时判断就可以了;对于情况二,可以在dfs结束但无输出时输出。

更多的细节请看代码。

完整代码

#include <cstdio>
#include <cstdlib>
using namespace std;
#define S 20//开到2*8-1+1=16就够了,为了保险开大点
int n=8;//用n代替8,如果扩大棋盘大小,改变n一样能运行
bool a[S][S],fh[S],fl[S],fzx[S],fyx[S];//a数组记录棋盘情况
void input(){//输入
	char ipt[S];
	bool flag=0;
	for(int i=1;i<=n;i++){
		scanf("%s",ipt+1);//ipt+1能让字符串下标从1开始,老技巧了
		for(int j=1;j<=n;j++){
			if(ipt[j]=='Q'){
				if(a[i][j]||fh[i]||fl[j]||fzx[i+j-1]||fyx[i-j+n])//可以不判断a[i][j],但为了代码的整齐,还是加一下
					flag=1;//为防止没读完数据RE的情况,我们用flag标记
				a[i][j]=fh[i]=fl[j]=fzx[i+j-1]=fyx[i-j+n]=1;//标记这个皇后占领的地方
			}//不用判断是'.'的情况,它又不会改变什么东西
		}
	}
	if(flag) puts("No Answer"),exit(0);//输入就错了,无解
}
void output(){//输出
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			if(a[i][j]) putchar('Q');//putchar比printf快
			else putchar('.');
		puts("");//puts自带换行
	}
	exit(0);//数据保证唯一解或无解,输出完一个解就能走人了
}
void dfs(int x){//dfs本体
	if(x==n+1) output();//搜到第9行,说明有解,输出
	else if(fh[x]) dfs(x+1);//这一行有皇后,直接下一行
	else{
	    for(int y=1;y<=n;y++){//枚举这一行的格子
		    if(a[x][y]||fh[x]||fl[y]||fzx[x+y-1]||fyx[x-y+n]) continue;//这个点被占领就跳过
		    a[x][y]=fh[x]=fl[y]=fzx[x+y-1]=fyx[x-y+n]=1;
		    dfs(x+1);//下一行
		    a[x][y]=fh[x]=fl[y]=fzx[x+y-1]=fyx[x-y+n]=0;//回溯
		}
    }
}
int	main(){//极简主函数
	input();
	dfs(1);
	puts("No Answer");//如果没调用到output就说明无解
	return 0;
}

标签:fzx,ARC001C,题解,dfs,fh,皇后,fyx,fl
From: https://www.cnblogs.com/caijianhong/p/solution-ARC001C.html

相关文章

  • 题解 UVA12265【贩卖土地 Selling Land】
    postedon2022-09-2414:33:29|under题解|sourceproblem一个黑白矩阵,求以每个点为右下角,能围出的周长最大的全白矩形的周长。\(n\leq2000\)。solution试图进行......
  • 焦点科技编程挑战赛2022题解
    比赛说明:比赛在四个学校开展,南理南航南农和矿大。题目查找文本差异要求origin和dest中分别包含1000w+条数据dest对数据进行了打乱操作,即origin和dest中相同数据行的......
  • CF1598F RBS 题解
    题意给\(n\)个串,求将这\(n\)个串以任意顺序接起来的最大的是合法括号序列的前缀数。分析\(n\)很小,考虑状压dp。有一个很典的转化是将(看成\(+1\),将)看成\(-......
  • CF 1743 题解
    比赛链接:https://codeforces.com/contest/1743题解:AB水题//bySkyRainWind#include<cstdio>#include<vector>#include<cstring>#include<iostream>#include......
  • week3题解
    1.寄包柜   看到题目最容易想到开二位数组但数据量过大,因此需要map#include<bits/stdc++.h>usingnamespacestd;map<int,map<int,int>>a;这里开了一个map......
  • el-date-picker 等 点击无反应不回显问题解决
    参考链接:https://blog.csdn.net/QQ2856639881/article/details/116918081?spm=1001.2101.3001.6661.1&depth_1-utm_relevant_index=1最近在做一个动态表单回显。数据嵌套......
  • vue项目中eslint报“Missing space before function parentheses”的问题解决
    原文链接:https://blog.csdn.net/u011523953/article/details/1067718681、问题原因:使用eslint时,严格模式下,报错Missingspacebeforefunctionparentheses(函数括号前缺少......
  • 【题解】CF1748D ConstructOR
    前言这道题十分诈骗,比赛的时候以为是根据二进制除法原理,解同余方程,然后考试时候就没做出来QAQ。这篇题解是构造解法,至于官方题解是啥我也不知道,看这官方题解的性质十分诡......
  • P8816 [CSP-J 2022] 上升点列 题解
    题目传送门:luoguP8816[CSP-J2022]上升点列这是一道简单的dp题。定义到达指两点的曼哈顿距离是\(1\)。我们考虑设状态\(f(i,j)\)表示考虑结尾是第\(i\)个点,增......
  • P6406 [COCI2014-2015#2] Norma 题解
    前言洛谷上很多大佬都写的CDQ分治的解法。但看了某篇大佬的线段树解法,受益匪浅,于是决定写一篇题解来记录一下这种解法。前置知识:单调栈,线段树题目通道题目描述给......