有点复杂的一道题目,还是用深搜,不过在这道题目中我们是一个小方格一个小方格地进行深搜,同时由于每个小方格有四个顶点,我们一般抓左上角的顶点。假设该顶点的位置为(x,y),那么我们就首先添加‘\’,然后判断添加之后是否会使得左上角的顶点的计数不对,或者让右下的顶点的计数超过上限,这里有一个部分需要注意,对于左上的顶点由于我们是最后一次处理,所以这个顶点的计数要求会很严,也就是必须相等,其他的顶点,后续可能都会使得计数增加,所以其他的三个点的计数不能超过上限也就行了。同时每次添加了一条线之后都要判断是否会形成环,如果形成了环就要将这种情况舍去。同时要对我们处理的当前列进行特判,如果是最后一列,那么就要判断是否会导致错误,同时要更新下一次处理的行号以及列号。具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
const int maxn = 10;
int N,n,point[maxn][maxn];
char data[maxn][maxn];
bool link[maxn][maxn][maxn][maxn];
bool vis[maxn][maxn];
int dx[] = { 1, 1, -1, -1 };
int dy[] = { -1, 1, 1, -1 };
bool found;
void Loop(int nx,int ny,int f_x,int f_y){
if (found || nx<0 || nx>n || ny<0 || ny>n || !link[nx][ny][f_x][f_y]) return;
if (vis[nx][ny]){
found = true;
return;
}
vis[nx][ny] = true;
for (int i = 0; i < 4; i++){
int newx = nx + dx[i];
int newy = ny + dy[i];
if (newx!=f_x||newy!=f_y)
Loop(newx, newy,nx,ny);
}
}
bool exist(int curx,int cury){
found = false;
memset(vis, 0, sizeof(vis));
vis[curx][cury] = true;
Loop(curx + 1, cury + 1,curx,cury);
Loop(curx - 1, cury - 1,curx,cury);
Loop(curx + 1, cury - 1,curx,cury);
Loop(curx - 1, cury + 1,curx,cury);
return found;
}
bool dfs(int row,int col){
if (col == n){
if (data[row][col] != '.'&&point[row][col] != data[row][col] - '0')
return false;
row++; col = 0;
if (row == n){
for (int j = 0; j <= n; j++){
if (data[row][j] != '.'&&point[row][j] != data[row][j] - '0')
return false;
}
return true;
}
else{
if (dfs(row,col)) return true;
return false;
}
}
int curx = row, cury = col;
point[curx][cury]++;
point[curx + 1][cury + 1]++;
link[curx][cury][curx + 1][cury + 1] = true;
link[curx + 1][cury + 1][curx][cury] = true;
if (data[curx][cury] != '.'&&point[curx][cury] != data[curx][cury] - '0'){
}
else if (data[curx + 1][cury + 1] != '.'&&point[curx + 1][cury + 1] > data[curx + 1][cury + 1] - '0'){
}
else if (!exist(curx,cury)){
col++;
if (dfs(row, col)) return true;
col--;
}
point[curx][cury]--;
point[curx + 1][cury + 1]--;
link[curx][cury][curx + 1][cury + 1] = false;
link[curx + 1][cury + 1][curx][cury] = false;
point[curx][cury + 1]++;
point[curx + 1][cury]++;
link[curx][cury+1][curx+1][cury] = true;
link[curx+1][cury][curx][cury+1] = true;
if (data[curx][cury+1] != '.'&&point[curx][cury+1] > data[curx][cury+1] - '0'){
}
else if (data[curx + 1][cury] != '.'&&point[curx + 1][cury] > data[curx + 1][cury] - '0'){
}
else if (data[curx][cury]!='.'&&point[curx][cury]!=data[curx][cury]-'0'){
}
else if (!exist(curx, cury+1)){
col++;
if (dfs(row, col)) return true;
col--;
}
point[curx][cury + 1]--;
point[curx + 1][cury]--;
link[curx][cury + 1][curx + 1][cury] = false;
link[curx + 1][cury][curx][cury + 1] = false;
return false;
}
int main(){
cin >> N;
while (N--){
cin >> n;
for (int i = 0; i <= n; i++){
for (int j = 0; j <= n; j++){
cin >> data[i][j];
}
}
memset(link,0,sizeof(link));
memset(point, 0, sizeof(point));
memset(vis, 0, sizeof(vis));
dfs(0, 0);
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;
}
}
}