AtCoder - ABC 326 - D - ABC Puzzle (DFS)

2024-03-28 14:04
文章标签 dfs atcoder abc puzzle 326

本文主要是介绍AtCoder - ABC 326 - D - ABC Puzzle (DFS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

看了很多题解都是写了一大坨,看起来非常的混乱,然而自己去写的时候又不可避免的写了一坨,只能尽可能的去优化代码可读性。


Time Limit: 4 sec / Memory Limit: 1024 MB

问题陈述

给你一个整数 N N N 和长度为 N N N 的字符串 R R R C C C ,它们由 A 、 B A、B AB C C C 组成。请解决下面的问题。

有一个 N × N N×N N×N 网格。所有单元格最初都是空的。您最多可以在每个单元格中写入 A 、 B A、B AB C C C 中的一个字符。(也可以让单元格为空)。

确定是否有可能满足以下所有条件,如果有可能,请打印一种满足这些条件的方法。

每一行和每一列正好包含一个 A、一个 B和一个 C。写入 i − t h i-th ith 行中最左边的字符与 R R R 中的 i − t h i-th ith 字符相匹配。写在 i − t h i -th ith 列中最顶端的字符与 C C C i − t h i -th ith 字符匹配。

限制因素

N N N 是介于 3 3 3 5 5 5 之间的整数,包括首尾两个整数。 R R R C C C 是长度为 N N N 的字符串,由 ABC组成。

输入

输入内容由标准输入法提供,格式如下

N
R
C

输出

如果无法填充网格以满足问题陈述中的条件,则单行打印 “No”。
否则,按以下格式打印一种填充网格的方法:

Yes
​A1
A2​ 
⋮
AN

第一行应包含 “是”。随后 N N N 行中的 i − t h i-th ith 应包含长度为 N N N 的字符串 A i A_i Ai​ 。

  • 如果 A i A_i Ai​ 的第 j j j 字符是 “.”,则表示从上往下 i − t h i-th ith 行和从左往右 j − t h j-th jth 列中的单元格为空。
  • 如果 A i A_i Ai 的第 j j j 个字符是 “A”,那么它表示 "A " 写在从上往下第 i i i 行、从左往上第 j j j 列的单元格中。
  • 如果 A i A_i Ai​ 的第 j j j 个字符是 “B”,那么它表示 "B "被写在从上往下第 i i i 行、从左往上第 j j j 列的单元格中。
  • 如果 A i A_i Ai​ 的第 j j j 个字符是 “C”,那么它表示 "C "被写在从上往下第 i i i 行、从左往上第 j j j 列的单元格中。

如果有多种正确的填充网格的方法,您可以打印其中任何一种。

Sample Input 1

5
ABCBC
ACAAB

Sample Output 1

Yes
AC..B
.BA.C
C.BA.
BA.C.
..CBA

对于这题4s的时间限制,并且联想到之前做过的八皇后问题,就想到可以用DFS来解决。

题目要求每行每列都只能有各一个 A , B , C A,B,C A,B,C 且都必须有这三个字母,我们可以以答案数组的层数同时作为dfs的层数,然后在搜到每一层的时候把这一层应有的 A , B , C A,B,C A,B,C 三个字母全部填上,这样我们就保证了每一行有且仅有一对 A , B , C A,B,C A,B,C 所以我们仅仅需要再判断一下每一列是否满足要求即可。
在这里就可以转化为八皇后模型了,开三个判断列的数组,每个对应一个字母,如果可以填就填上。

对于如何在一层里填上三个字母,我们需要一次性填上三个。
假如你写出了三层循环来找字母,那么你填出来之后就变成了一行只有一个字母了。
所以写出一个三层循环,每一层循环的是每个字母要填的位置,这里把重叠的位置全部continue掉。

代码:

#include<iostream>
#include<cstring>
#pragma warning(disable: 4996)
using namespace std;
const int N = 10;int n;char g[N][N];	//答案数组
char a[N];
char b[N];//判断某一列是否已经有A或B或C
bool a_line[N];
bool b_line[N];
bool c_line[N];//u代表的是层数,即答案数组的x轴
void dfs(int u) {if (u == n + 1) {	//如果搜满了所有层,就进行判断for (int i = 1; i <= n; i++) {		//第一次判断for (int j = 1; j <= n; j++) {	//判断最左边的字母是不是符合字符串A的顺序if (g[i][j] != '.') {if (g[i][j] == a[i])break;else return;}if (j == n && g[i][j] == '.')return;	//要是搜完了所有的甚至都没一个字母,直接跳}}for (int i = 1; i <= n; i++) {		//第二次判断for (int j = 1; j <= n; j++) {	//判断最上边的字母是不是符合字符串B的顺序if (g[j][i] != '.') {		//以下同理if (g[j][i] != b[i])return;else break;}if (j == n && g[j][i] == '.')return;}}
//-------------------------------------------------------------------------------------//输出答案cout << "Yes" << endl;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cout << g[i][j];}puts("");}exit(0);	//直接从这里终结整个程序}
//--------------------------------------------------------------------------------------//搜索部分//这里枚举的i,j,k是字母A,B,C填入的位置for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if (i == j)continue;	//A和B不能填到一个位置,直接continuefor (int k = 1; k <= n; k++) {if (i == k || j == k)continue;	//A和C,B和C不能填到一个位置if (!a_line[i] && !b_line[j] && !c_line[k]){//如果这一列还没有被填入过相应的字母g[u][i] = 'A', g[u][j] = 'B', g[u][k] = 'C';a_line[i] = b_line[j] = c_line[k] = 1;dfs(u + 1);//搜下一层//回溯状态g[u][i] = g[u][j] = g[u][k] = '.';a_line[i] = b_line[j] = c_line[k] = 0;}}}}
}
//----------------------------------------------------------------------------------------------
int main() {cin >> n;scanf("%s%s", a + 1, b + 1);for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {g[i][j] = '.';}}dfs(1);//如果没找到答案就直接输出Nocout << "No";return 0;
}

这篇关于AtCoder - ABC 326 - D - ABC Puzzle (DFS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855816

相关文章

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

AtCoder Beginner Contest 370 Solution

A void solve() {int a, b;qr(a, b);if(a + b != 1) cout << "Invalid\n";else Yes(a);} B 模拟 void solve() {qr(n);int x = 1;FOR(i, n) FOR(j, i) qr(a[i][j]);FOR(i, n) x = x >= i ? a[x][i]: a[i][x];pr2(

nyoj99(并查集+欧拉路+dfs)

单词拼接 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串。 前一个单词的结尾应该与下一个单词的道字母相同。 如 aloha dog arachnid gopher tiger rat   可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整

【CF】E. Anya and Cubes(双向DFS)

根据题意的话每次递归分3种情况 一共最多25个数,时间复杂度为3^25,太大了 我们可以分2次求解第一次求一半的结果,也就是25/2 = 12,记录结果 之后利用剩余的一半求结果 s-结果 = 之前记录过的结果 就可以 时间复杂度降低为 3 ^ (n/2+1) 题目链接:http://codeforces.com/contest/525/problem/E #include<set

力扣 797. 所有可能路径【DFS】

1. 题目 2. 代码 DFS , 直接见代码 class Solution {public:vector<int> path;vector<vector<int>> res; // 结果集void dfs(vector<vector<int>>& graph, int cur, int n){// 找出所有从节点 0 到节点 n-1 的路径// 下标从 0 开始的if (

CF Bayan 2015 Contest Warm Up B.(dfs+暴力)

B. Strongly Connected City time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/probl