题意:在一个n*n(n7)网格中,有些交叉点上有数字。你的任务是给每个格子画一条斜线(“/”和“\”),使得每个交叉点的数字等于和他们相连的斜线条数,且这些斜线不会构成环。

分析:方法是dfs,交叉点数字解决方法是以放入“\”和“/”为搜索对象,方格的端的有数字就减一,没数字就剪枝,其中有很多剪枝,比如每当搜索完一个方格后,方格的左端点如果是数字,那么数字应该为0,依次类推,方格处于右端,左上应该为0等等。其中关键难点是判断是否有环。看一位大佬的解法,以最新放进去的方格内容为对象,搜索方格四周,当点重复被搜索时,说明存在环。

bool loop(int r, int c, int f) { //判断是否有环if (vis[r][c] == mark) return true;vis[r][c] = mark; //每次都给他赋值,这个mark没有实际意义,只是避免和上次搜索重复for (int i = 0; i < 4; i++) {if ((i ^ 1) == f) continue; //i的相反方向是否等于fint fr = r + dr[i], fc = c + dc[i]; //搜索四周if (edge[r][c][fr][fc] == 0) continue; //判断是否有边if (loop(fr, fc, i)) return true;}return false;
}

写的很简单,但非常实用!

#include <cstdio>
#include <cstring>
#include <cctype>const int UP = 7 + 5;
const int dr[4] = { -1, 1, -1, 1 }; //左上,右下,右上,左下
const int dc[4] = { -1, 1, 1, -1 };
const int udr[2] = { 0, 0 }; //反斜杠和斜杠的上方坐标
const int udc[2] = { 0, 1 };
const int ddr[2] = { 1, 1 }; //反斜杠和斜杠的下方坐标
const int ddc[2] = { 1, 0 };int n, N, finish, mark, vis[UP][UP];
char grid[UP][UP], ans[UP][UP], edge[UP][UP][UP][UP];
//ans[r][c] 与 grid[r][c], grid[r][c+1], grid[r+1][c], grid[r+1][c+1] 相关联
//r与c的下标从1开始void renew(int r1, int c1, int r2, int c2) { //恢复状态if (isdigit(grid[r1][c1])) grid[r1][c1]++;if (isdigit(grid[r2][c2])) grid[r2][c2]++;
}bool loop(int r, int c, int f) { //判断是否有环if (vis[r][c] == mark) return true;vis[r][c] = mark; //每次都给他赋值,这个mark没有实际意义,只是避免和上次搜索重复for (int i = 0; i < 4; i++) {if ((i ^ 1) == f) continue; //i的相反方向是否等于fint fr = r + dr[i], fc = c + dc[i]; //搜索四周if (edge[r][c][fr][fc] == 0) continue; //判断是否有边if (loop(fr, fc, i)) return true;}return false;
}bool dfs(int id) {if (id == finish) return true;if (id % N == 0) return dfs(id + 1); //该位置不做考虑,只是下一个位置的过渡int r = id / N, c = id % N;int jr = r + udr[0], jc = c + udc[0]; //判断该位置的数字是否大于0所用for (int i = 0; i < 2; i++) {int ufr = r + udr[i], ufc = c + udc[i];int dfr = r + ddr[i], dfc = c + ddc[i];if (isdigit(grid[ufr][ufc]) && grid[ufr][ufc] - 1 < '0') continue;if (isdigit(grid[dfr][dfc]) && grid[dfr][dfc] - 1 < '0') continue;if (isdigit(grid[ufr][ufc])) grid[ufr][ufc]--;if (isdigit(grid[dfr][dfc])) grid[dfr][dfc]--;if (grid[jr][jc] > '0') { //剪枝1renew(ufr, ufc, dfr, dfc);continue;}if (r == n) { //剪枝2int sr = r + ddr[1], sc = c + ddc[1];if (grid[sr][sc] > '0') {renew(ufr, ufc, dfr, dfc);continue;}}if (c == n) { //剪枝3int sr = r + udr[1], sc = c + udc[1];if (grid[sr][sc] > '0') {renew(ufr, ufc, dfr, dfc);continue;}}if (r == n && c == n) { //剪枝4int sr = r + ddr[0], sc = c + ddc[0];if (grid[sr][sc] > '0') {renew(ufr, ufc, dfr, dfc);continue;}}ans[r][c] = i;edge[ufr][ufc][dfr][dfc] = edge[dfr][dfc][ufr][ufc] = 1;mark++;if (loop(dfr, dfc, -1)) {edge[ufr][ufc][dfr][dfc] = edge[dfr][dfc][ufr][ufc] = 0;renew(ufr, ufc, dfr, dfc);continue;}if (dfs(id + 1)) return true;edge[ufr][ufc][dfr][dfc] = edge[dfr][dfc][ufr][ufc] = 0;renew(ufr, ufc, dfr, dfc);}return false;
}int main() {int T;scanf("%d", &T);while (T--) {scanf("%d", &n);N = n + 1;for (int r = 1; r <= N; r++) scanf("%s", grid[r] + 1);memset(vis, 0, sizeof(vis));memset(edge, 0, sizeof(edge));mark = 1;finish = N * N;dfs(N + 1);for (int r = 1; r <= n; r++) {for (int c = 1; c <= n; c++) {if (ans[r][c] == 0) printf("\\");else printf("/");}printf("\n");}}return 0;
}

UVA - 11694 Gokigen Naname(dfs)相关推荐

  1. 三十二、图的创建深度优先遍历(DFS)广度优先遍历(BFS)

    一.图的基本介绍 为什么要有图 前面我们学了线性表和树 线性表局限于一个直接前驱和一个直接后继的关系 树也只能有一个直接前驱也就是父节点 当我们需要表示多对多的关系时, 这里我们就用到了图. 图的举例 ...

  2. 【 MATLAB 】离散傅里叶级数(DFS)及 IDFS 的 MATLAB 实现

    有关离散傅里叶级数(DFS)我之前也写过一些博文,例如:离散周期信号的傅里叶级数(DFS) 这里我再次给出标准公式. 分析式: 其中: 综合式: 这里我必须先声明,关于分析式和综合式前面那个系数1/N ...

  3. 部署分布式文件系统(DFS)

    部署分布式文件系统(DFS) 使用 DFS 命名空间,可以将位于不同服务器上的共享文件夹组合到一个或多个逻辑结构的命名空间.每个命名空间作为具有一系列子文件夹的单个共享文件夹显示给用户.但是,命名空间 ...

  4. Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)

    对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图. import java.util.ArrayList; import java ...

  5. 广度优先搜索(BFS)与深度优先搜索(DFS)

    一.广度优先搜索(BFS) 1.二叉树代码 # 实现一个二叉树 class TreeNode:def __init__(self, x):self.val = xself.left = Nonesel ...

  6. 7.9模拟赛T1图的遍历(dfs)

    图的遍历(dfs) [题目描述] 对于一个有向图G来说,我们存在一个经典的遍历算法,就是DFS (深度优先搜索遍历).将G以1号点为起点进行DFS后,我们可以 得到G的一棵DFS遍历树T.就此,我们可 ...

  7. 7.6 T1 深度优先搜索(dfs)

    深度优先搜索(dfs) [题目描述] sol:50pts随便写写,就是大众分了,直接n2dpOK,100分要找点规律,需要数学头脑 官方题解 //#include <bits/stdc++.h& ...

  8. 二叉树的深度优先遍历(DFS)与广度优先遍历(BFS)

    二叉树的深度优先遍历(DFS)与广度优先遍历(BFS) 深度优先遍历:从根节点出发,沿着左子树方向进行纵向遍历,直到找到叶子节点为止.然后回溯到前一个节点,进行右子树节点的遍历,直到遍历完所有可达节点 ...

  9. 深度优先遍历(DFS)- Letter CasePermutation - Combinations

    深度优先遍历(DFS) 思路:从图中一个未访问的顶点V开始,沿着一条路一直走到尽头,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到尽头-,不断递归重复此过程,直到所有顶点都遍历完成. 特 ...

最新文章

  1. 【跃迁之路】【732天】程序员高效学习方法论探索系列(实验阶段489-2019.2.22)...
  2. 电气接线+线号管正确方向=电工接线好习惯!你有吗?
  3. AndroidStudio中调试时一直显示waiting for debugger
  4. CCCC L2 007 家庭房产 并查集
  5. 数字三角形(洛谷-P1118)
  6. 2017.9.4 栅栏 失败总结
  7. 如何运行vue项目(从gethub上download的开源项目)
  8. 电力技术监督导则_会议报道:2019年电力行业燃煤发电企业节能监督管理专业技术人员及燃煤发电机组能效水平对标管理办法培训班...
  9. 数据库 | 远程连接centos7上数据库
  10. Android UI学习之SeekBar
  11. 前端dvajs与umijs
  12. 程序员考证书,有用吗?
  13. 安装已经下载好的whl文件
  14. C# BitConverterExt 对BitConverter的GetBytes 方法扩展
  15. MI(mutal information)and Entropy
  16. 组合预测模型:bagging
  17. python 使用qq登陆搜狗微信搜索
  18. 编程之美 2.1 求二进制中1的个数
  19. Word调整页眉与标题/正文的距离
  20. SolidWorks六角螺母添加倒角2种方法

热门文章

  1. ConcurrentHashMap的源码分析-put方法第三阶段
  2. MyBatis 实际使用案例-typeHandlers【重点】
  3. 高仿真的类-BeanWrapper
  4. 创建订单 - 扣除商品库存与订单状态保存
  5. 文件操作-打开文件方式以及写入和追加数据
  6. spring事务环境搭建
  7. AbstractQueuedSynchronizer源码解析
  8. cv岗工作做什么_中字头施工单位的党建岗是做什么的?
  9. 201205阶段二FFmpeg编码
  10. ubuntu18.04 VirtualBox 开启虚拟机出错 Kernel driver not installed (rc=-1908)