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编译原 ...
随机推荐
- 【Java每日一题】20170228
20170227问题解析请点击今日问题下方的“[Java每日一题]20170228”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; import jav ...
- SSM+Netty项目结合思路
最近正忙于搬家,面试,整理团队开发计划等工作,所以没有什么时间登陆个人公众号,今天上线看到有粉丝想了解下Netty结合通用SSM框架的案例,由于公众号时间限制,我不能和此粉丝单独沟通,再此写一篇手记分 ...
- Netty实战三之Netty的组件和设计
有关Netty,我们可以从两个视角来讨论Netty:类库的视角以及框架的视角,对于使用Netty编写高效的.可重用的和可维护的代码来说,两者缺一不可. Netty解决了两个响应的关注领域,可以大致标志 ...
- js 从一个对象中找到属性值相等的集合
getobjs: function(objs, key, value) { var result = []; for (var i in objs) { var obj = $(objs[i]); i ...
- Ubuntu下解压缩文件
记录Ubuntu下各种压缩和解压方式: .tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)—————— ...
- <python3-cookbook>第一章:数据结构和算法
第一章:数据结构和算法 介绍:python3-cookbook这本书是高级用法,不是小白使用书目的:写作目的是记录下自己学习这本书的过程以及收获书籍地址:https://python3-cookboo ...
- Android Studio多渠道打包(二)
虽然多渠道打包的方式有很多种,那么今天我要说的通过工具的形式进行多渠道打包 首先,打开Android studio,找到顶部Build,点开 选择红色部分,里面的编辑框可以帮助我们更快的熟悉Gradl ...
- View体系第一篇:基础
View体系的学习内容为学习刘望舒先生博客总结的内容,大家可到他的博客看到更详细的内容. 一.view之间的继承关系 Viewground用来包裹其他view.在平常的使用中,我们不会直接用到View ...
- javascript实现的浏览器下载文件
function download(src) { var $a = document.createElement('a'); $a.setAttribute("href", src ...
- 关于正餐智能POS6.0.1.1改版后,订单模块无法进行部分退款的FAQ
适用版本:智能POS正餐V6.0.1.1+ 适用情况:订单模块,无法输入自定义金额进行部分退款. 原因:为让报表统计的数据更准确. 改版之后仍可适用部分退款的情况: 1.口碑先付订单,可在口碑模块,选 ...