题解 UVA11694 【Gokigen Naname谜题 Gokigen Naname】
题目
题解
考场上连暴力都不会打的码农题,深搜是真的难 /kk
前置问题
- 怎么输出“\”
cout<<"\\";
2.怎么处理不在一个环里,可以考虑并查集,\(f\)数组的下标为该元素位于矩阵中的个数
例如: 在$3 \times 3 $的矩阵中 \((2,2)\) 坐标指的是交点的坐标
可以表示为 5
(1,1)---->1
(1,2)---->2
(1,3)---->3
(1,4)---->4
(2,1)---->5
(2,2)---->6
(2,3)---->7
(2,4)---->8
(3,1)---->9
(3,2)---->10
(3,3)---->11
(3,4)---->12
如果两个点位于同一个并查里那就不能连边,如果不在,那么就可以连边
此并查集不同于一般的并查集
其初值不能为0 ,而且其不能进行路径压缩,自己想一下就会明白,如果路径压缩会这样
3 .样例输入其实是有问题的
样例输入:
2
3
1.1.
...0
.3..
..2.
5
.21...
..33.0
......
..33..
0..33.
....11
输出:
\//
\\\
/\/
/\\//
//\\\
\\\//
\/\\/
///\\
再说一遍这是spj不要看样例不对就以为自己写错了,可能算法不一样也就不一样
1.思路
思路1 :
上面的前置知识中已经解决了一个最大的问题,环的问题,剩下的就是怎么搜索
从\((1,1)\)开始搜索,逐行进行处理,因为每一个格子要不放""要不就是放"/"因为是spj我们可以考虑首先放"",然后判断放"/",种完全不反悔的深搜,一搜到底,适用的范围貌似不是很大
思路2:
可以考虑从\((1,1)\)开始搜索, 首先考虑放“/” 如果不合法,那就回溯,重新放置"",这种想法想的很容易但是想要实现十分困难,反正这位大佬码量惊人,居然还真写出来了%%%%
对于第一种思路的使用
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int N = 150;
const int dx[4] = {0, 0, 1, 1};
const int dy[4] = {0, 1, 0, 1};
int n ;
int mapp[50][50] ;
int cnt[N][N]; // 这个点已经连接了几条边
int lim[N][N]; //一个格子可以拓展的方向
char ans[N][N]; // 一开始我是char想直接输出,我也不知为啥不行
int f[N*N];
bool flag;
void print() {
puts("");
for(int i = 1 ; i <= n;i++) {
for(int j = 1 ; j <= n ;j++) {
cout<<mapp[i][j] <<" ";
}
puts("");
}
}
//检验自己输入的函数
bool check(int x,int y){
if(mapp[x][y] == -1) return true;
if(cnt[x][y] <= mapp[x][y] && cnt[x][y] + lim[x][y] >= mapp[x][y]) return true;
return false ;
}
//判断合法
int findf(int x) {
if( !f[x] ) return x;
return f[x] = findf(f[x]);
}
void dfs(int x, int y) {
if (y == n) {
y = 1 , x++;
}
if(x == n ) {
flag = 1;
return ;
}
// 这里因为是逐行搜索,n++后,不会检查第 n+1 行的交点,第n+1行下面已经没有格子了
int f1 , f2 ,pd = 0;
++cnt[x][y], ++cnt[x + 1][y + 1];
--lim[x][y],--lim[x+1][y+1],--lim[x+1][y],--lim[x][y+1];
//因为一个格子只能放一种 \ 或者 / 所以 一个格子的四个角都要减少拓展的方向
//第一种情况 \
for(int i = 0 ; i < 4 ;i++) {
int tx = x + dx[i] , ty = y + dy[i];
if(!check(tx,ty)) {
pd = 1;
break;
}
}
if(!pd) {
f1 = findf((x - 1) * n + y),f2 = findf(x * n + y + 1 ) ;
if(f1 != f2) {
ans[x][y] = 1; // 1 ---------> \
f[f1] = f2;
dfs(x,y+1);
if(flag) return ;
f[f1] = 0;
}
}
--cnt[x][y], --cnt[x+1][y+1];
++cnt[x+1][y] ,++cnt[x][y+1];
// 更换为另一种情况 /
pd = 0;
for(int i = 0 ; i < 4 ;i++) {
int tx = x + dx[i] , ty = y + dy[i];
if(!check(tx,ty)) {
pd = 1;
break;
}
}
if(!pd) {
f1 = findf(x * n + y ),f2 = findf((x - 1) * n + y + 1) ;
if(f1 != f2) {
ans[x][y] = 0; // 0 ------------> /
f[f1] = f2;
dfs(x,y+1);
if(flag) return ;
f[f1] = 0;
}
}
--cnt[x+1][y] ,--cnt[x][y+1];
++lim[x][y] ,++lim[x+1][y+1] ,++lim[x+1][y], ++lim[x][y + 1] ;
//深搜回溯
}
int main() {
// freopen("gokigen.in","r",stdin);
// freopen("gokigen.out","w",stdout);
int T;
cin>> T;
while(T--) {
//
memset(cnt , 0 , sizeof(cnt));
memset(f,0,sizeof(f));
flag = 0;
//多组不清我是sb
cin>> n; n++;
for(int i = 1 ; i <= n ;i++) {
for(int j = 1 ; j <= n ;j++) {
lim[i][j] = 4;
char ch = getchar() ;
if(ch == '\n' && i + j != 2 * n ) ch = getchar();
if(ch == '.') mapp[i][j] = -1;
else mapp[i][j] = (ch - '0');
if((i == 1 || i == n) && (j == 1 || j == n)) {
lim[i][j] = 1;
continue;
}
if(i == 1 || i == n || j == 1 || j == n) lim[i][j] = 2;
}
}
dfs(1,1);
for(int i = 1 ; i < n ;i++) {
for(int j = 1 ; j < n ;j++) {
if(!ans[i][j]) cout<<"/";
else cout <<"\\";
}
puts("");
}
}
return 0;
}
题解 UVA11694 【Gokigen Naname谜题 Gokigen Naname】的更多相关文章
- [NOIP补坑计划]NOIP2016 题解&做题心得
感觉16年好难啊QAQ,两天的T2T3是不是都放反了啊…… 场上预计得分:100+80+100+100+65+100=545(省一分数线280) ps:loj没有部分分,部分分见洛咕 题解: D1T1 ...
- UVA11694 Gokigen Naname题解
目录 写在前面 Solution Code 写在前面 UVA的题需要自己读入一个 \(T\) 组数据,别被样例给迷惑了 Solution 每个格子只有两种填法且 \(n \le 7\),暴力搜索两种填 ...
- Uva 11694 Gokigen Naname
基本思路是Dfs: 1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1), ...
- UVA11694-Gokigen Naname(DFS进阶)
Problem UVA11694-Gokigen Naname Accept: 76 Submit: 586Time Limit: 10000 mSec Problem Description I ...
- [题解]玩具谜题(toy)
玩具谜题(toy) 来源:noip2016 提高组 day1 [题目描述] 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个 ...
- NOIP2016DAY1题解
https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=33%2C83 T1:玩具谜题 题解: 沙茶模拟 #includ ...
- 递归的神奇之处在于你会发现问题竟然解决了--解N皇后谜题有感
看sicp看到8皇后谜题, 突然兴致来了,尝试独立解决(scheme代码的好处在于,即使你瞟了眼答案, 也不会有任何收获, 除了知道那儿有一坨神秘的括号和英文字符外但Python代码就不同了),成功了 ...
- 算法(第四版)C# 习题题解——2.5
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更方便的版本见:https ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
随机推荐
- Spring AOP 实战运用
Spring AOP 实战 看了上面这么多的理论知识, 不知道大家有没有觉得枯燥哈. 不过不要急, 俗话说理论是实践的基础, 对 Spring AOP 有了基本的理论认识后, 我们来看一下下面几个具体 ...
- 【代码周边】MongoDB与Mysql对比以及插入稳定性分析(指定主键的影响)
在数据库存放的数据中,有一种特殊的键值叫做主键,它用于惟一地标识表中的某一条记录.也就是说,一个表不能有多个主键,并且主键不能为空值. 无论是MongoDB还是MySQL,都存在着主键的定义. 对于M ...
- JDBC(五)—— 批量插入数据
批量插入数据 @Test public void testInsert() throws Exception { Connection conn = null; PreparedStatement p ...
- 痞子衡嵌入式:MCUBootUtility v3.0发布,开始支持LPC, Kinetis啦
-- 痞子衡维护的NXP-MCUBootUtility工具距离上一个版本(v2.4.0)发布过去2个半月了,这一次痞子衡为大家带来了全新版本v3.0.0,从这个版本开始,NXP-MCUBootUtil ...
- 从 Java 代码到 CPU 指令
从 Java 代码到 CPU 指令 我们都知道,编写的 Java 代码,最终还是要转化为 CPU 指令才能执行的.为了理解 Java 内存模型的作用,我们首先就来回顾一下从 Java 代码到最终执行的 ...
- ContactCollections Design Report
通讯录的设计采用了分层+接口+面向对象+文件操作+方法实现 分三层实现,共使用了四个包,实现业务数据访问和界面的分离 contactaccess包实现对文件的访问 包括数据访问 ...
- 【小菜学网络】MAC地址详解
上一小节介绍了以太网帧的结构,以及帧中各个字段的作用.参与以太网通讯的实体,由以太网地址唯一标识.以太网地址也叫做 MAC 地址,我们对它仍知之甚少. 以太网地址在不同场景,称谓也不一样,常用叫法包括 ...
- 自定义注解,更优雅的使用MP分页功能
分页功能使用 MP的分页功能是通过MyBatis的插件实现的,使用起来也非常简单.下面先介绍下使用方式. step1:配置分页插件 @Configuration @EnableTransactionM ...
- Linux下Oracle 11G XE 安装笔记
操作系统 [oracle@RAC02 ~]$ lsb_release -aLSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:cor ...
- Spring Security OAuth2.0认证授权五:用户信息扩展到jwt
历史文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二:搭建资源服务 Spring Security OA ...