-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
#define MAXN 15
-
#define limit(x,y) ((x>=0) && (x<n) && (y>=0) && (y<n))
-
int d[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
-
int n;
-
int group[4][2*MAXN-1];
-
int g[4][2*MAXN-1][3];//前两维与上面group一致,后面一维0:未确定 1:确定不放 2:确定放
-
int board[MAXN][MAXN];
-
int done;
-
-
int color(int x, int y)
-
{
-
int list[MAXN*MAXN][2];//que for bfs
-
int t,xx,yy,p,i;
-
list[0][0]=x;
-
list[0][1]=y;
-
board[x][y]=2;
-
t=1;p=0;
-
while(p<t){
-
for(i=0; i<4; i++){
-
xx=d[i][0]+list[p][0];
-
yy=d[i][1]+list[p][1];
-
if(limit(xx,yy) && (board[xx][yy]==0)){
-
board[xx][yy]=2;
-
list[t][0]=xx;
-
list[t][1]=yy;
-
t++;
-
}
-
}
-
p++;
-
}
-
return 0;
-
}
-
-
int enclosed_intersections()
-
{
-
int i,j,k;
-
for(i=0; i<n; i++){
-
if(board[0][i]==0)
-
color(0,i);
-
if(board[n-1][i]==0)
-
color(n-1,i);
-
}
-
-
for(i=1; i<n-1; i++){
-
if(board[i][0]==0)
-
color(i,0);
-
if(board[i][n-1]==0)
-
color(i,n-1);
-
}
-
-
k=0;//统计封闭交叉点
-
for(i=0;i<n;i++){
-
for(j=0;j<n;j++){
-
if(board[i][j]==0)
-
k++;
-
}
-
}
-
return k;
-
}
-
-
int update(int board[MAXN][MAXN])
-
{
-
int i,j,k,l,l1,l2;
-
int flag;//标记是否通过推断确定了某些新位置
-
-
/* 根据每行的约束条件进行推断 */
-
flag=0;
-
for(i=0;i<n;i++){
-
if(group[0][i]>g[0][i][2]+g[0][i][0])
-
return -1;//目标棋子数不能超过已放棋子+剩余位置数
-
//剩余位置都要放
-
if((g[0][i][0]>0) && (group[0][i]==g[0][i][2]+g[0][i][0])){
-
flag=1;
-
for(j=0;j<n;j++){
-
if(board[i][j]==-1)
-
board[i][j]=1;
-
}
-
}
-
//剩余位置都不能放
-
if((g[0][i][0]>0) && (group[0][i]==g[0][i][2])){
-
flag=1;
-
for(j=0;j<n;j++){
-
if(board[i][j]==-1)
-
board[i][j]=0;
-
}
-
}
-
}
-
if(flag)
-
return 1;
-
/* 根据每列的约束条件进行判断 */
-
for(j=0;j<n;j++){
-
if(group[1][j]>g[1][j][2]+g[1][j][0])
-
return -1;
-
if((g[1][j][0]>0) && (group[1][j]==g[1][j][2]+g[1][j][0])){
-
flag=1;
-
for(i=0;i<n;i++){
-
if(board[i][j]==-1)
-
board[i][j]=1;
-
}
-
}
-
if((g[1][j][0]>0) && (group[1][j]==g[1][j][2])){
-
flag=1;
-
for(i=0;i<n;i++){
-
if(board[i][j]==-1)
-
board[i][j]=0;
-
}
-
}
-
}
-
if(flag)
-
return 1;
-
-
/* 根据每条对角线的约束条件进行判断 */
-
for(k=0;k<2*n-1;k++){
-
if(group[2][k]>g[2][k][2]+g[2][k][0])
-
return -1;
-
if((g[2][k][0]>0) && (group[2][k]==g[2][k][2]+g[2][k][0])){
-
flag=1;
-
if(k<=n-1){
-
l1=0;
-
l2=k;
-
}else{
-
l1=k-n+1;
-
l2=n-1;
-
}
-
for(l=l1;l<=l2;l++){
-
if(board[l][k-l]==-1)
-
board[l][k-l]=1;
-
}
-
}
-
if((g[2][k][0]>0) && (group[2][k]==g[2][k][2])){
-
flag=1;
-
if(k<=n-1){
-
l1=0;
-
l2=k;
-
}else{
-
l1=k-n+1;
-
l2=n-1;
-
}
-
for(l=l1;l<=l2;l++){
-
if(board[l][k-l]==-1)
-
board[l][k-l]=0;
-
}
-
}
-
}
-
if(flag)
-
return 1;
-
-
/* 根据每条反对角线的约束条件进行判断 */
-
for(k=0;k<2*n-1;k++){
-
if((group[3][k]>g[3][k][2]+g[3][k][0]))
-
return -1;
-
if((g[3][k][0]>0) && (group[3][k]==g[3][k][2]+g[3][k][0])){
-
flag=1;
-
if(k<=n-1){
-
l1=n-1-k;
-
l2=n-1;
-
}else{
-
l1=0;
-
l2=2*n-2-k;
-
}
-
for(l=l1;l<l2;l++){
-
if(board[l][k+l-n+1]==-1)
-
board[l][k+l-n+1]=1;
-
}
-
}
-
if((g[3][k][0]>0) && (group[3][k]==g[3][k][2])){
-
flag=1;
-
if(k<=n-1){
-
l1=n-1-k;
-
l2=n-1;
-
}else{
-
l1=0;
-
l2=2*n-2-k;
-
}
-
for(l=l1;l<l2;l++){
-
if(board[l][k+l-n+1]==-1)
-
board[l][k+l-n+1]=0;
-
}
-
}
-
}
-
if(flag)
-
return 1;
-
return 0;
-
}
-
-
int deduce(int board[MAXN][MAXN])
-
{
-
int i,j,k,flag;
-
flag=1;
-
while(flag){
-
memset(g,0,sizeof(g));
-
for(i=0;i<n;i++){
-
for(j=0;j<n;j++){
-
k=board[i][j];
-
g[0][i][k+1]++;
-
g[1][j][k+1]++;
-
g[2][i+j][k+1]++;
-
g[3][j-i+n-1][k+1]++;
-
}
-
}
-
-
flag=update(board);
-
if(flag==-1)
-
return -1;
-
}
-
return 0;
-
}
-
-
int init()//读入数据和完成初始化
-
{
-
int i;
-
memset(group,0,sizeof(group));
-
memset(board,0xFF,sizeof(board));
-
-
for(i=0;i<n;i++){
-
scanf("%d", &group[0][i]);
-
}
-
for(i=0;i<n;i++)
-
scanf("%d", &group[1][i]);
-
for(i=0;i<n*2-1;i++)
-
scanf("%d", &group[2][i]);
-
for(i=0;i<n*2-1;i++)
-
scanf("%d", &group[3][i]);
-
-
board[0][0]=group[2][0];
-
board[n-1][n-1]=group[2][2*n-2];
-
board[n-1][0]=group[3][0];
-
board[0][n-1]=group[3][2*n-2];
-
-
deduce(board);
-
return 0;
-
}
-
-
int solutionfound(int* x,int* y)
-
{
-
int i,j;
-
for(i=0; i<n;i++){
-
for(j=0; j<n;j++){
-
if(board[i][j]==-1){
-
*x=i;
-
*y=j;
-
return 0;
-
}
-
}
-
}
-
return 1;
-
}
-
-
int right()
-
{
-
int i,j,k;
-
memset(g,0,sizeof(g));
-
for(i=0;i<n;i++){
-
for(j=0;j<n;j++){
-
k=board[i][j];
-
g[0][i][k+1]++;
-
g[1][j][k+1]++;
-
g[2][i+j][k+1]++;
-
g[3][j-i+n-1][k+1]++;
-
}
-
}
-
-
for(i=0;i<n;i++){
-
if(g[0][i][2] != group[0][i])
-
return 0;
-
if(g[1][i][2] != group[1][i])
-
return 0;
-
}
-
-
for(i=0;i<2*n-1;i++){
-
if(g[2][i][2] != group[2][i])
-
return 0;
-
if(g[3][i][2] != group[3][i])
-
return 0;
-
}
-
return 1;
-
}
-
-
//依次对棋盘位置搜索,尝试放与不放棋子来找出棋盘布局
-
int attempt()
-
{
-
int oldboard[MAXN][MAXN];
-
int x,y,k;
-
if(solutionfound(&x,&y)){
-
if(right()){
-
done=1;
-
}
-
return 0;
-
}
-
-
memcpy(oldboard,board,sizeof(board));//save original chessboard
-
board[x][y]=1;//try to putting chess
-
k=deduce(board);
-
if(k!=-1){
-
attempt();
-
if(done)
-
return 0;
-
}
-
-
memcpy(board,oldboard,sizeof(board));//restore old chessboard
-
board[x][y]=0;//try to no putting chess
-
k=deduce(board);
-
if(k!=-1){
-
attempt();
-
if(done)
-
return 0;
-
}
-
memcpy(board,oldboard,sizeof(board));
-
return 0;
-
}
-
-
int run()
-
{
-
done=0;
-
attempt();
-
return 0;
-
}
-
-
int main()
-
{
-
int test_case,T;
-
freopen("0503in.txt","r",stdin);
-
//freopen("0503out.txt","w",stdout);
-
//setbuf(stdout,NULL);
-
scanf("%d", &T);
-
for(test_case=1;test_case<=T;test_case++)
-
{
-
scanf("%d", &n);
-
init();
-
run();
-
printf("%d\n", enclosed_intersections());
-
}
-
return 0;
-
}
Input:
10
1
1
1
1
1
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
15
15 15 15 15 15 15 15 15 15 15 15 15 15 15 15
15 15 15 15 15 15 15 15 15 15 15 15 15 15 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
5
1 3 2 3 1
0 2 2 2 4
0 0 1 3 0 2 2 1 1
0 0 0 2 3 2 1 2 0
15
15 2 13 13 13 13 13 13 13 13 13 13 13 2 15
15 2 13 13 13 13 13 13 13 13 13 13 13 2 15
1 2 2 2 3 4 5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5 4 3 2 2 2 1
1 2 2 2 3 4 5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5 4 3 2 2 2 1
10
10 2 2 2 2 2 2 2 2 9
10 2 2 2 2 2 2 2 2 9
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0
1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1
10
0 8 2 2 2 2 2 2 8 0
0 8 2 2 2 2 2 2 8 0
0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 0 0
0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 0 0
10
1 1 1 1 1 1 1 1 1 1
0 0 0 0 10 0 0 0 0 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
15
2 2 2 2 2 2 2 1 2 2 2 2 2 2 2
2 2 2 2 2 2 2 1 2 2 2 2 2 2 2
1 0 1 0 1 0 1 0 1 0 1 0 1 0 15 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 15 0 1 0 1 0 1 0 1 0 1 0 1 0 1
15
12 6 6 5 5 5 5 5 8 4 4 4 4 4 11
12 6 6 5 4 4 4 9 4 3 4 4 4 4 15
0 2 2 4 0 6 2 2 2 10 0 12 2 2 2 2 7 6 3 3 3 3 2 2 2 2 2 2 1
1 2 2 1 1 2 2 4 4 5 3 6 3 6 1 6 3 7 2 6 2 5 2 4 1 2 2 2 1
Out:
iLyn:acm02 Cute$ time ./0503
0
0
0
3
48
64
36
0
0
122
real 0m0.008s
user 0m0.001s
sys 0m0.003s
阅读(1378) | 评论(0) | 转发(0) |