Problem UVA11694-Gokigen Naname

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

2
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进阶)的更多相关文章

  1. UVA11694 Gokigen Naname题解

    目录 写在前面 Solution Code 写在前面 UVA的题需要自己读入一个 \(T\) 组数据,别被样例给迷惑了 Solution 每个格子只有两种填法且 \(n \le 7\),暴力搜索两种填 ...

  2. 题解 UVA11694 【Gokigen Naname谜题 Gokigen Naname】

    题目 题解 考场上连暴力都不会打的码农题,深搜是真的难 /kk 前置问题 怎么输出"\" cout<<"\\"; 2.怎么处理不在一个环里,可以考虑 ...

  3. Uva 11694 Gokigen Naname

    基本思路是Dfs: 1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1), ...

  4. dfs进阶

    当自己以为自己深搜(其实就是暴力啦)小成的时候,发现没有题目的积累还是很难写出程序,自己真的是太年轻了:总结一下就是做此类题看是否需要使用vis数组优化以及继续搜索的条件或者满足答案的条件.以下为2题 ...

  5. hdu 1426:Sudoku Killer(DFS深搜,进阶题目,求数独的解)

    Sudoku Killer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  6. 0基础算法基础学算法 第八弹 递归进阶,dfs第一讲

    最近很有一段时间没有更新了,主要是因为我要去参加一个重要的考试----小升初!作为一个武汉的兢兢业业的小学生当然要去试一试我们那里最好的几个学校的考试了,总之因为很多的原因放了好久的鸽子,不过从今天开 ...

  7. 搜索进阶课件,视频,代码(状态压缩搜索,折半搜索,dfs,bfs总结)

    链接:https://pan.baidu.com/s/1-svffrprCOO4CtQoCTQ9hQ 提取码:h909 复制这段内容后打开百度网盘手机App,操作更方便哦

  8. ACM进阶计划

    ACM进阶计划ACM队不是为了一场比赛而存在的,为的是队员的整体提高.大学期间,ACM队队员必须要学好的课程有:lC/C++两种语言l高等数学l线性代数l数据结构l离散数学l数据库原理l操作系统原理l ...

  9. [转]ACM进阶计划

    ACM进阶计划  大学期间,ACM队队员必须要学好的课程有: lC/C++两种语言 l高等数学 l线性代数 l数据结构 l离散数学 l数据库原理 l操作系统原理 l计算机组成原理 l人工智能 l编译原 ...

随机推荐

  1. Java_Queue接口

    Queue接口 1.英文 a)         Queue 队列 b)         Deque ,Double ender queue缩写,双向队列 2.Queue接口 除了基本的 Collect ...

  2. Centos6.5安装MySQL5.6备忘记录

    Centos6.5安装MySQL5.6 1. 查看系统状态 [root@itzhouq32 tools]# cat /etc/issue CentOS release 6.5 (Final) Kern ...

  3. python基础学习(一) 第一个python程序

    1. 使用python/python3解释器的方式 按照惯例,我们都是以Hello world作为一门程序语言的开始,进行如下的操作: 在桌面上新建一个hello-python文件夹 进入hello- ...

  4. Java并发编程-看懂AQS的前世今生

    在具备了volatile.CAS和模板方法设计模式的知识之后,我们可以来深入学习下AbstractQueuedSynchronizer(AQS),本文主要想从AQS的产生背景.设计和结构.源代码实现及 ...

  5. 【Web前端】用CSS3实现弹幕

    初版 用css3来实现弹幕确实比较简单,只需要设置动画让弹幕从屏幕右侧移动到屏幕左侧即可,一开始是这样实现的 .danmu { position: fixed; left: %; animation: ...

  6. 有序列表ol,无序列表ul,定义列表dl

    ====================非常重要=================无序列表ul中有一个type属性四个属性值type="disc" 实心圆点(默认) type=&q ...

  7. 原生JS实现随着鼠标滚动到元素位置触发对应css3动画,简单易用滚动监测

    预览链接:http://www.vanwee.cn/%E6%BB%9A%E5%8A%A8%E7%9B%91%E5%90%AC/ <style> body{overflow-x: hidde ...

  8. js 分页插件(jQuery)

    参考:http://www.jb51.net/article/117191.htm 侵删 css 部分 @charset "utf=8"; *{ box-sizing: borde ...

  9. mybatis 自动生成文件配置

    maven 依赖配置: <!-- sql server --><dependency> <groupId>com.microsoft.sqlserver</g ...

  10. 图说OOP基础(一)

    本文用图形化的形式描述OOP的相关知识.对OOP进行系统化的梳理,以便掌握,仅供学习分享使用,如有不足之处,还请指正. 涉及知识点: OOP的相关知识 OOP知识总图 [Object-Orientat ...