UVA11694-Gokigen Naname(DFS进阶)
Accept: 76 Submit: 586
Time Limit: 10000 mSec
Problem Description

Input
The first line of the input file contains an integer N (N < 25) which denotes the total number of test cases. The description of each test case is given below: The first line of each test case contains a single integer n (2 ≤ n ≤ 7), the number of cells along each of the sides in the square grid. Then follow n+1 lines containing the contents of the intersections of the grid cells. Each such line will contain a string of n + 1 characters, either a digit between 0 and 4, inclusive, or a period (‘.’) indicating that there is no number at this intersection (arbitrarily many lines may connect to it).
Output
For each test case print n lines, each line containing exactly n characters. Each character should either be a slash or a backslash, denoting how the corresponding grid cell is filled.
Sample Input
3
1.1.
...0
.3..
..2.
5
.21...
..33.0
......
..33..
0..33.
....11
Sample Output
\//
\\\
/\/
/\\//
//\\\
\\\//
\/\\/
///\\
题解:我感觉这个题挺难的,DFS的思路还比较直接,但是维护哪些东西比较迷茫。首先肯定有一个原图,然后要维护一下各点目前已经连了几条边,最关键的是要维护每个节点最多还能连几条边(用于剪枝)。判环的问题丢给并查集。DFS的时候从上到下,从左到右,每次连一条边更新维护的东西,要更新的东西比较多,回溯的时候别漏了。这里的并查集有必要提一句,这里不能路径压缩,因为回溯时是一种类似删除节点的操作,简单画个图就能发现如果只在回溯时修改当前节点的父节点为原来的父节点是不对的。因此这里不路径压缩,并查集基本上就是个链表的作用。剪枝有两个:1、如果一个节点连出的边数超了肯定要剪枝。2、利用lim数组,预估在最多的情况下能连几条边,如果少于目标边数,剪枝。
#include <bits/stdc++.h> using namespace std; const int maxn = ; int n;
int gra[maxn][maxn], lim[maxn][maxn];
int cur[maxn][maxn], ans[maxn][maxn];
int dx[] = { ,,, };
int dy[] = { ,,, }; int pre[maxn*maxn]; int findn(int x) {
return x == pre[x] ? x : findn(pre[x]);
} inline bool ok(int x, int y) {
if (gra[x][y] == -) return true;
if (cur[x][y] <= gra[x][y] && cur[x][y] + lim[x][y] >= gra[x][y]) return true;
return false;
} bool dfs(int x, int y) {
if (y == n) x++, y = ;
if (x == n) return true; cur[x][y]++, cur[x + ][y + ]++;
lim[x][y]--, lim[x + ][y]--, lim[x][y + ]--, lim[x + ][y + ]--; bool can_put = true;
for (int i = ; i < ; i++) {
int xx = x + dx[i], yy = y + dy[i];
if (!ok(xx, yy)) { can_put = false; break; }
}
if (can_put) {
int f1 = findn((x - )*n + y), f2 = findn(x*n + y + );
if (f1 != f2) {
ans[x][y] = ;
int tmp = pre[f2];
pre[f2] = f1;
if (dfs(x, y + )) return true;
pre[f2] = tmp;
}
} cur[x][y]--, cur[x + ][y + ]--;
cur[x][y + ]++, cur[x + ][y]++;
can_put = true;
for (int i = ; i < ; i++) {
int xx = x + dx[i], yy = y + dy[i];
if (!ok(xx, yy)) { can_put = false; break; }
}
if (can_put) {
int f1 = findn(x*n + y), f2 = findn((x - )*n + y + );
if (f1 != f2) {
ans[x][y] = -;
int tmp = pre[f1];
pre[f1] = f2;
if (dfs(x, y + )) return true;
pre[f1] = tmp;
}
} cur[x][y + ]--, cur[x + ][y]--;
lim[x][y]++, lim[x + ][y]++, lim[x][y + ]++, lim[x + ][y + ]++;
return false;
} int main()
{
//freopen("input.txt", "r", stdin);
int iCase;
scanf("%d", &iCase);
while (iCase--) {
scanf("%d", &n);
n++;
char ss[maxn];
for (int i = ; i <= n * n; i++) pre[i] = i;
memset(cur, , sizeof(cur)); for (int i = ; i <= n; i++) {
scanf("%s", ss + );
for (int j = ; j <= n; j++) {
if (ss[j] == '.') gra[i][j] = -;
else gra[i][j] = ss[j] - ''; lim[i][j] = ; if ((i == || i == n) && (j == || j == n)) {
lim[i][j] = ;
continue;
}
if (i == || j == || i == n || j == n) {
lim[i][j] = ;
}
}
} dfs(, ); for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) {
if (ans[i][j] == ) printf("\\");
else printf("/");
}
printf("\n");
}
}
return ;
}
UVA11694-Gokigen Naname(DFS进阶)的更多相关文章
- UVA11694 Gokigen Naname题解
目录 写在前面 Solution Code 写在前面 UVA的题需要自己读入一个 \(T\) 组数据,别被样例给迷惑了 Solution 每个格子只有两种填法且 \(n \le 7\),暴力搜索两种填 ...
- 题解 UVA11694 【Gokigen Naname谜题 Gokigen Naname】
题目 题解 考场上连暴力都不会打的码农题,深搜是真的难 /kk 前置问题 怎么输出"\" cout<<"\\"; 2.怎么处理不在一个环里,可以考虑 ...
- Uva 11694 Gokigen Naname
基本思路是Dfs: 1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1), ...
- dfs进阶
当自己以为自己深搜(其实就是暴力啦)小成的时候,发现没有题目的积累还是很难写出程序,自己真的是太年轻了:总结一下就是做此类题看是否需要使用vis数组优化以及继续搜索的条件或者满足答案的条件.以下为2题 ...
- hdu 1426:Sudoku Killer(DFS深搜,进阶题目,求数独的解)
Sudoku Killer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 0基础算法基础学算法 第八弹 递归进阶,dfs第一讲
最近很有一段时间没有更新了,主要是因为我要去参加一个重要的考试----小升初!作为一个武汉的兢兢业业的小学生当然要去试一试我们那里最好的几个学校的考试了,总之因为很多的原因放了好久的鸽子,不过从今天开 ...
- 搜索进阶课件,视频,代码(状态压缩搜索,折半搜索,dfs,bfs总结)
链接:https://pan.baidu.com/s/1-svffrprCOO4CtQoCTQ9hQ 提取码:h909 复制这段内容后打开百度网盘手机App,操作更方便哦
- ACM进阶计划
ACM进阶计划ACM队不是为了一场比赛而存在的,为的是队员的整体提高.大学期间,ACM队队员必须要学好的课程有:lC/C++两种语言l高等数学l线性代数l数据结构l离散数学l数据库原理l操作系统原理l ...
- [转]ACM进阶计划
ACM进阶计划 大学期间,ACM队队员必须要学好的课程有: lC/C++两种语言 l高等数学 l线性代数 l数据结构 l离散数学 l数据库原理 l操作系统原理 l计算机组成原理 l人工智能 l编译原 ...
随机推荐
- springMVC_02hello案例
1.导入jar包 commons-logging-1.1.1.jar jackson-annotations-2.5.4.jar jackson-core-2.5.4.jar jackson-data ...
- Maven(五)Eclipse配置Maven插件
较新版本的Eclipse内置Maven插件 1. 设置installation 一般不适用内置的 指定核心程序的位置 2. 设置user settings 指定本地仓库的位置 1.如果setting. ...
- 浅谈spring中AOP以及spring中AOP的注解方式
AOP(Aspect Oriented Programming):AOP的专业术语是"面向切面编程" 什么是面向切面编程,我的理解就是:在不修改源代码的情况下增强功能.好了,下面在 ...
- 详解Java中对象的软、弱和虚引用的区别
对于大部分的对象而言,程序里会有一个引用变量来引用该对象,这是最常见的引用方法.除此之外,java.lang.ref包下还提供了3个类:SoftReference.WeakReference和Phan ...
- 10个常见的JavaScript BUG
译者按: 安全起见,在开发中我基本不用==. 原文: 10 COMMON JAVASCRIPT BUGS AND HOW TO AVOID THEM 译者: Fundebug 为了保证可读性,本文采用 ...
- css 小知识点:inline/inline-block/line-height
inline: 此元素会被显示为内联元素,元素前后没有换行符.因此:无法设置宽度和高度- inline-block: 行内块元素.元素前后没有换行符(CSS2.1 新增的值) 用通俗的话讲,就是不独占 ...
- Java中static与final
修饰变量:static:静态变量,是属于这个类的final :常量,只能赋值一次static final:静态常量,必须立即初始化(同时具有static.final的特点) 修饰方法:static:静 ...
- 【转录】原来Github上的README.md文件这么有意思——Markdown语言详解
之前一直在使用github,也在上面分享了不少的项目和Demo,每次创建新项目的时候,使用的都是默认的README.md文件,也不曾对这个文件有过什么了解.但是在看到别人写的项目的README.md里 ...
- JavaScript面向对象编程指南(四) 对象
第4章 对象 4.1 从数组到对象 对象的组成:变量名.{}.用逗号分割的属性.用冒号分割的键/值对. var f={ name:'alen', // 可以在属性名上加引号 age:12 }; 对象文 ...
- Salesforce 自定义标签在代码中的应用
自定义标签简介 Salesforce 中自定义标签(Custom Label)的作用是存储一般性的文本,可以用于 Apex.Visualforce 页面.Lightning 组件等地方,用于显示提示信 ...