原题连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5547
题意:
给出4*4的板,要求填入1-4的数字,每行,每列,4个2*2的方格内都要有1-4.
思路:
每找到一个数字,就把它所能影响的范围内,该数字标记为已经出现过,每个被更新位置的cnt减1,当cnt值为1的时候,表示这个位置答案唯一确定。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
char b[5][5];
int vis[5][5];
struct Node{
int x,y;
int cnt;
int num[5];
}node[5][5];
queue<Node> q;
void update( int x, int y, int n ){
for( int j = 0; j < 4; j++ ){
if( node[x][j].num[n] == 0 ){
node[x][j].num[n] = 1;
node[x][j].cnt--;
}
if( node[x][j].cnt == 1 && !vis[x][j] ){
vis[x][j] = 1;
q.push( node[x][j] );
}
}
for( int i = 0; i < 4; i++ ){
if( node[i][y].num[n] == 0 ){
node[i][y].num[n] = 1;
node[i][y].cnt--;
}
if( node[i][y].cnt == 1 && !vis[i][y] ){
vis[i][y] = 1;
q.push( node[i][y] );
}
}
int xx = x/2;
int yy = y/2;
int sx = xx == 0 ? 0 : 2;
int tx = xx == 0 ? 2 : 4;
int sy = yy == 0 ? 0 : 2;
int ty = yy == 0 ? 2 : 4;
for( int i = sx; i < tx; i++ ){
for( int j = sy; j < ty; j++ ){
if( node[i][j].num[n] == 0 ){
node[i][j].num[n] = 1;
node[i][j].cnt--;
}
if( node[i][j].cnt == 1 && !vis[i][j]){
vis[i][j] = 1;
q.push( node[i][j] );
}
}
}
}
void getans( Node t ){
int x = t.x;
int y = t.y;
for( int i = 1; i <= 4; i++ ){
if( node[x][y].num[i] == 0 ){
b[x][y] = '0' + i;
update( x, y, i );
break;
}
}
}
int main(){
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
int cas = 1;
while( T-- ){
while( !q.empty() ){
q.pop();
}
for(int i = 0; i < 4; i++ ){
scanf("%s",b[i]);
}
for( int i = 0; i < 4; i++ ){
for( int j = 0; j < 4; j++ ){
node[i][j].x = i;
node[i][j].y = j;
node[i][j].cnt = 4;
for( int k = 0; k <= 4; k++ ){
node[i][j].num[k] = 0;
}
vis[i][j] = 0;
}
}
for( int i = 0; i < 4; i++ ){
for(int j = 0; j < 4; j++ ){
if( b[i][j] != '*' ){
node[i][j].cnt = 0;
vis[i][j] = 1;
int num = b[i][j] - '0';
update( i,j,num);
}
}
}
while( !q.empty() ){
Node t = q.front();
q.pop();
getans( t );
}
printf("Case #%d:\n",cas++);
for( int i = 0; i < 4; i++ ){
printf("%s\n",b[i]);
}
}
return 0;
}