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. 三个线程T1,T2,T3.保证顺序执行的三种方法

    经常看见面试题:有三个线程T1,T2,T3,有什么方法可以确保它们按顺序执行.今天手写测试了一下,下面贴出目前想到的3种实现方式 说明:这里在线程中我都用到了sleep方法,目的是更容易发现问题.之前 ...

  2. 【Java每日一题】20170210

    20170209问题解析请点击今日问题下方的“[Java每日一题]20170210”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; public cla ...

  3. 安装PyCharm

    安装包下载 本文以CentOS上PyCharm安装为例来介绍,安装包的下载地址:https://www.jetbrains.com/pycharm/download/ 官网提供了windows,mac ...

  4. Idea 15 激活

    https://www.cnblogs.com/moko/p/5012006.html 1.把补丁下载到自己的电脑上 2.打开idea,help->edit custom VM options ...

  5. 华硕笔记本的U盘启动

    开机以后有两种方式: 1:按住ESC键,在弹出的见面直接选择USB启动进入. 2:按F2进BLOS进入,在boot里面原则第一个,找到USB作为第一启动项,再按F10保存一下即可.

  6. Android Lifecycle使用

    引言 Lifecycle 是官方提供的架构组件之一,目前已经是稳定版本,Lifecycle 组件包括LifecycleOwner.LifecycleObserver.Lifecycle 组件是执行操作 ...

  7. js之单例模式

    单例模式是指一个类,只有一个实例.实现的思路是,创建实例时候加判断,如果有实例则返回,如果没有就new一个,并返回. 第一步: 创建类. function Waiter(id, name, salar ...

  8. POJ1201 Intervals(差分约束)

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 28416   Accepted: 10966 Description You ...

  9. iphone屏幕镜像怎么用 手机投屏电脑

    手机看视频有的时候总会感觉到累,屏幕太小看的不够爽又或者用手一直拿着手机看累得慌.我就就喜欢看电视因为电视屏幕大看的爽,而且现在很多手机视频都可以往电视上投影视频,那么iphone屏幕镜像怎么用? 使 ...

  10. MySql数据库实现分布式的主从结构

    最近学习了关于使用MySql数据的实现主动结构的原理,在以前的并发访问低的场景一下,一般一台性能高的服务器作为一个MySql数据,就可以满足业务的增删改查场景,但是随着网络用户的增加 当出现高并发,高 ...