基本思路是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. Ubuntu 用 pptp 建立 vpn 服务

    1.下载pptp sudo apt-get install pptpd 2.配置pptp 须要改动配置下面的文件: pptpd.conf文件:配置链接后的主机ip和能够分配的内存范围 vi /etc/ ...

  2. Head First设计模式学习笔记

    最近在学C++,直接语法之后觉得不太有意思,直接做项目又觉得太肤浅.正好之前一直想学设计模式来着,可惜之前一直在玩C,所以没有机会深入学习,于是决定用C++把设计写一遍.看了点GOF的<设计模式 ...

  3. iOS面试题05-父子控制器、内存管理

    内存管理.父子控制器面试题 1.建立父子关系控制器有什么用 回答:1>监听屏幕选中 2>如果想拿到你当前的很小的一个控制器所在的导航控制器必须要跟外面比较大的控制器建立父子关系,才能一层一 ...

  4. objective-C学习笔记(九)ARC

    ARC叫自动引用计数Automatic Reference Counting.针对堆上的对象,管理对象的创建和释放. 哪些对象受ARC管理: OC对象指针 Block指针 使用_attribute_( ...

  5. BZOJ 1050 旅行comf

    题目如下: 题目描述 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边 ...

  6. [Swust OJ 385]--自动写诗

    题目链接:http://acm.swust.edu.cn/problem/0385/ Time limit(ms): 5000 Memory limit(kb): 65535    Descripti ...

  7. [置顶] 老孟 DB2 V9.7 ESE(一)产品部署 基于centOS 6.4

    本文安装系统CENTOS 6.4 DB2位数64 安装中涉及目录位置各位可自行定义 生产系统为安全和性能考虑,一般将DB2实例目录.日志目录.归档日志目录.表空间目录区分开,可建立/db2home / ...

  8. linux下安装PHP的redis扩展

    1.安装redis ①下载:https://github.com/phpredis/phpredis.git ②cd phpredis   进入目录 ③/usr/local/php/bin/phpiz ...

  9. socket 通信 入门3 android 客户端 C# 服务端

    这是一个android端操控服务器的例子  就是发送简单指令到服务器  然后服务器响应什么的... 当然这里是未完成的  只是简单展示一下大致思路 首先连接建立起来后  服务端给客户端一条信息  告诉 ...

  10. delphi 编译生成ipa文件

    找IPA文件 开发模式ipa文件和发布模式ipa文件,路径不同. http://www.itnose.net/detail/6101808.html 一.开发模式Development 不需要真机,可 ...