题意
给定一个N*N可能不完整的数字矩阵需要填满,矩阵数字0->9,要求每一行每一列不能有重复数字。同时给出一些行和一些列的限制,要求从某个方向看某一行或一列“看到的”数字要与之相符。
题解
限制条件很强,要敢于暴力搜索。
代码
/****************************************\
* Author : ztx
* Title : K - Towers
* ALG : 搜索
* CMT :
* Time :
\****************************************/
#include <cstdio>
#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define rep(i,l,r) for(i=(l);i< (r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
#define rev(i,r,l) for(i=(r);i> (l);i--)
typedef long long ll ;
typedef double lf ;
int CH , NEG ;
template <typename TP>inline void read(TP& ret) {
ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
if (CH == '-') NEG = true , CH = getchar() ;
while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
if (NEG) ret = -ret ;
}
template <typename TP>inline void readc(TP& ret) {
while (ret=getchar() , ret<'!') ;
//while (CH=getchar() , CH>'!') ;
}
template <typename TP>inline void reads(TP *ret) {
ret[0]=0;while (CH=getchar() , CH<'!') ;
while (ret[++ret[0]]=CH,CH=getchar(),CH>'!') ;
ret[ret[0]+1]=0;
}
#include <cstring>
#define maxn 7LL
const int dx[4] = {0,0,1,-1} ;
const int dy[4] = {1,-1,0,0} ;
#define left 0
#define right 1
#define up 2
#define down 3
#define row 0
#define col 1
int n , tott ;
int a[maxn][maxn] , px[maxn*maxn] , py[maxn*maxn] ;
bool exist[2][maxn][10] ;
inline bool check(int i,int j,int dir,int tot) {
int look = 0 , now = 0 , exist = 0 ;
if (dir == left) j = 1 ;
if (dir == right) j = n ;
if (dir == up) i = 1 ;
if (dir == down) i = n ;
for (;i>=1&&i<=n&&j>=1&&j<=n;i+=dx[dir],j+=dy[dir]) {
if (a[i][j]) exist ++ ;
if (a[i][j] > now) now = a[i][j] , look ++ ;
}
if (exist == n) return look == tot ;
return true ;
}
inline bool use(int i,int j,int x) {
if (exist[row][i][x]) return false ;
if (exist[col][j][x]) return false ;
a[i][j] = x ;
if (a[i][0] && !check(i,j,left,a[i][0])) return a[i][j] = 0 ;
if (a[i][n+1] && !check(i,j,right,a[i][n+1])) return a[i][j] = 0 ;
if (a[0][j] && !check(i,j,up,a[0][j])) return a[i][j] = 0 ;
if (a[n+1][j] && !check(i,j,down,a[n+1][j])) return a[i][j] = 0 ;
exist[row][i][x] = exist[col][j][x] = true ;
return true ;
}
#define unuse(i,j,x) a[i][j] = exist[row][i][x] = exist[col][j][x] = 0 ;
bool dfs(int p) {
if (p > tott) return true ;
int x ;
#define i px[p]
#define j py[p]
Rep (x,1,n) if (use(i,j,x)) {
if (dfs(p+1)) return true ;
unuse(i,j,x) ;
}
return false ;
#undef i
#undef j
}
int main() {
int T , ok , i , j ;
// #define READ
#ifdef READ
freopen(".in" ,"r",stdin ) ;
freopen(".out","w",stdout) ;
#endif
for (read(T) ; T -- ; ) {
tott = 0 ;
memset(exist,0,sizeof exist) ;
read(n) ;
ok = true ;
Rep (i,0,n+1) Rep (j,0,n+1) {
#define x a[i][j]
readc(x) ;
x = x == '-' ? 0 : x-'0' ;
if (!ok || i<1 || i>n || j<1 || j>n) continue ;
if (x) {
if (exist[row][i][x]) ok = false ;
if (exist[col][j][x]) ok = false ;
exist[row][i][x] = exist[col][j][x] = true ;
} else ++ tott , px[tott] = i , py[tott] = j ;
#undef x
}
if (ok)
Rep (i,1,n) {
if (a[i][0] && !check(i,i,left,a[i][0])) ok = false ;
if (a[i][n+1] && !check(i,i,right,a[i][n+1])) ok = false ;
if (a[0][i] && !check(i,i,up,a[0][i])) ok = false ;
if (a[n+1][i] && !check(i,i,down,a[n+1][i])) ok = false ;
}
if (ok && dfs(1)) {
Rep (i,1,n) {
Rep (j,1,n) printf("%d",a[i][j]) ;
puts("") ;
}
} else puts("no") ;
puts("") ;
}
#ifdef READ
fclose(stdin) ; fclose(stdout) ;
#else
getchar() ; getchar() ;
#endif
return 0 ;
}