基本思路是Dfs:

  1. 一个一个格子摆放,以每个各自的左上角的点为基准点代表格子,比如(0,0)代表(0,0)(0,1)(1,0)(1,1)组成的格子,(0,1)代表(0,1)(0,2)(1,1),(1,2)组成的格子,以此类推,即可一个一个格子按顺序摆放。

  2. 当摆放(x,y)时,比较分别放 \ 和放 / ,同时比较(x,y)的数值要求是否已经达到(不能多不能少,(x,y)必须刚好达到),其次比较另外的如(x+1,y),(x+1,y+1),(x,

y+1)是否已经超出要求。再者就是判断是否构成环,我采用了dfs的方法。

  3. 如何表示这个点连接几条斜线了呢?可以用一个数组保存,如point[i][j] 表示(i, j)连接了point[i][j]条斜线。而判断两个点是否连接可以用link[][][][],如link[a][b][c][d],表示link[a][b][c][d]是否连接。

  一点收获与感悟:最初写的时候,没有link数组,想用point[a][b]和point[c][d]是否同时大于1判断(a, b)与(c,d)是否连接,结果可想而知,这个错误明显了!发现这个错误后才加入了link数组。但这样只是解决了错误,还没有解决超时。刚开始写的时候只判断了(x,y)是否满足要求,没有判断其它点,后来一想,可能再给(x, y)(x+1, y+1)相连时,(x+1, y+1)连接的边数就超过(x+1, y+1)要求的边数了,所以要同时判断与(x,y)相连的点,这个判断一添,就没有超时了。

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 7 + 3;
char chess[MAXN][MAXN];
int point[MAXN][MAXN];
bool link[MAXN][MAXN][MAXN][MAXN];
int N;
int go[4][2] = {1,1, 1,-1, -1,-1, -1,1}; void Read() {
for(int i=0; i<N+1; ++ i) {
for(int j=0; j<N+1; ++ j) {
cin >> chess[i][j];
}
}
} bool vis[MAXN][MAXN];
bool found; void Loop(int x, int y, int a, int b) {
if(found || x<0 || x>N || y<0 || y>N || !link[x][y][a][b] ) {
return ;
}
if(vis[x][y]) {
found = true;
return ;
}
vis[x][y] = true;
for(int i=0; i<4; ++i) {
if( x+go[i][0]!=a || y+go[i][1]!=b ) {
Loop(x+go[i][0], y+go[i][1], x, y);
}
}
} bool Any(int x, int y) {
memset(vis, false, sizeof(vis));
found = false;
vis[x][y] = true;
Loop(x+1, y+1, x, y);
Loop(x-1, y-1, x, y);
Loop(x-1, y+1, x, y);
Loop(x+1, y-1, x, y);
return !found;
} bool Dfs(int r, int c) {
if(c == N) {
if( isdigit(chess[r][c]) && point[r][c] != chess[r][c] - '0') {
return false;
}
++ r; c = 0;
if(r == N) {
for(int i=0; i<N+1;i++) {
if(isdigit(chess[r][i]) && point[r][i] != chess[r][i] - '0') {
return false;
}
}
return true;
} else {
return Dfs(r, c);
}
}
int x = r, y = c;
point[x][y] ++;
point[x+1][y+1] ++;
link[x][y][x+1][y+1] = true;
link[x+1][y+1][x][y] = true;
if( isdigit(chess[x][y]) && point[x][y] != chess[x][y] - '0') {
;
} else if(isdigit(chess[x+1][y+1]) && point[x+1][y+1] > chess[x+1][y+1] - '0') {
;
} else if(Any(x, y)) {
++ y;
if(Dfs(x, y)) {
return true;
}
}
x = r, y =c;
link[x][y][x+1][y+1] = false;
link[x+1][y+1][x][y] = false;
point[x][y] --;
point[x+1][y+1] --; point[x][y+1] ++;
point[x+1][y] ++;
link[x][y+1][x+1][y] = true;
link[x+1][y][x][y+1] = true;
if( isdigit(chess[x][y]) && point[x][y] != chess[x][y] - '0') {
;
} else if(isdigit(chess[x][y+1]) && point[x][y+1] > chess[x][y+1] - '0') {
;
} else if(isdigit(chess[x+1][y]) && point[x+1][y] > chess[x+1][y] - '0') {
;
} else if(Any(x, y+1)) {
++ y;
if(Dfs(x, y)) {
return true;
}
}
x = r, y =c;
link[x][y+1][x+1][y] = false;
link[x+1][y][x][y+1] = false;
point[x][y+1] --;
point[x+1][y] --;
return false;
} void Work() {
memset(point, 0, sizeof(point));
memset(link, false, sizeof(link));
Dfs(0 ,0);
} void Print() {
for(int i=0; i<N; ++i) {
for(int j=0; j<N; ++j) {
if(point[i][j] && point[i+1][j+1] && link[i][j][i+1][j+1]) {
cout << "\\";
} else {
cout << "/";
}
}
cout << endl;
}
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T --) {
cin >> N;
Read();
Work();
Print();
}
return 0;
}

Uva 11694 Gokigen Naname的更多相关文章

  1. UVA11694 Gokigen Naname题解

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

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

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

  3. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

  4. UVA 10564 Paths through the Hourglass[DP 打印]

    UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...

  5. UVA 11404 Palindromic Subsequence[DP LCS 打印]

    UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...

  6. UVA&&POJ离散概率与数学期望入门练习[4]

    POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...

  7. UVA计数方法练习[3]

    UVA - 11538 Chess Queen 题意:n*m放置两个互相攻击的后的方案数 分开讨论行 列 两条对角线 一个求和式 可以化简后计算 // // main.cpp // uva11538 ...

  8. UVA数学入门训练Round1[6]

    UVA - 11388 GCD LCM 题意:输入g和l,找到a和b,gcd(a,b)=g,lacm(a,b)=l,a<b且a最小 g不能整除l时无解,否则一定g,l最小 #include &l ...

  9. UVA - 1625 Color Length[序列DP 代价计算技巧]

    UVA - 1625 Color Length   白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束   和模拟赛那道环形DP很想,计算这 ...

随机推荐

  1. android环境下解决java.io.IOException: Malformed ipv6异常的方法

    今天做客户端想服务端提交信息的时候,报出了如标题所显示的方法 方法以及参数如下: 输入的参数为:http://192.168.1.173:8080/Api/petinfo/petinfo?flag=a ...

  2. Ajax异步请求XMLHttpRequest对象Get请求

    $(function () { $("#btnGetDate").click(function () { var xhr; //第一步:创建异步请求的核心的对象: if (XMLH ...

  3. //相当于深拷贝一份dataArray。这样才不会改变dataArray本身的值

    //相当于深拷贝一份dataArray.这样才不会改变dataArray本身的值 NSMutableArray* commitDataArray = [NSKeyedUnarchiver unarch ...

  4. BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )

    对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...

  5. C语言,函数的声明与定义

    函数声明与定义 变量: 在讲变量前,先讲一下变量的声明和定义这两个概念. 声明一个变量,意味着向编译器描述变量的类型,但不为变量分配存储空间. 定义一个变量,意味着在声明变量的同时还要为变量分配存储空 ...

  6. .htaccess Rewrite apache重写和配置

    首先: 必须要空间支持 Rewrite 以及对站点目录中有 .htaccess 的文件解析,才有效. 如何让空间支持Rewrite 和 .htaccess 的文件解析呢 往下看 第一步:要找到apac ...

  7. ES6学习笔记:Module的基本用法

    export和import ES6实现了模块功能,试图解决JavaScript代码上的依赖和部署上的问题,取代现有的CommonJs的AMD规范,成为浏览器和服务器通用的模块解决方案. 模块功能有两个 ...

  8. React使用笔记(3)-React Event Listener

    Date: 2015-11-28 12:18 Category: Web Tags: JavaScript Author: 刘理想 [toc] 1. 构造基本结构 首先,我们先创建一个按钮,一个输入框 ...

  9. widget intent重复问题

    今天在做android widget时发现点击任意widget时只会更新最后一个widget 原来是requestCode的问题 Intent intent = new Intent(WidgetPr ...

  10. js函数预编译和声明语句被提升问题小结

    <!DOCTYPE html><html><head></head><body><script>//-------------- ...