POJ 2676

/*
九宫格问题,也有人叫数独问题
把一个9行9列的网格,再细分为9个3*3的子网格,
要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字,
即每行、每列、每个子网格内都不允许出现相同的数字。
 0是待填位置,其他均为已填入的数字。
要求填完九宫格并输出(如果有多种结果,则只需输出其中一种)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int map[10][10];//存图
int book[10][10];//标记点
int row[10][10];//每行用的数字
int col[10][10];//每列用的数字
int grid[10][10];//每个九宫格用的数字
int n;
int flag;//成功填满九宫格时赋1
void dfs(int x,int y)
{
    if(x==10){
        flag=1;
        return;
    }
    if(book[x][y]){
        if(y<9)//此行未到头,继续往前
            dfs(x,y+1);
        else//下一行行首
            dfs(x+1,1);
    }
    else{
        book[x][y]=1;
        int k=(x-1)/3*3+(y-1)/3+1;//得到处在第几个3 X 3的九宫格中,公式推导而出
        for(int i=1;i<=9&&!flag;i++){//记得判断flag,flag为1后,不用再搜索其他情况
            if(!row[x][i]&&!col[y][i]&&!grid[k][i]){
                map[x][y]=i;
                row[x][i]=1;
                col[y][i]=1;
                grid[k][i]=1;
                if(y<9)
                    dfs(x,y+1);
                else
                    dfs(x+1,1);
                if(!flag){//flag为0,取消当前位置取的数,继续搜索其他可能
                    row[x][i]=0;
                    col[y][i]=0;
                    grid[k][i]=0;
               }
            }
        }
        if(!flag)
           book[x][y]=0;
    }
    return;
}
int main()
{
    scanf("%d",&n);
    getchar();
    while(n--){
        flag=0;
        memset(book,0,sizeof(book));
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        memset(grid,0,sizeof(grid));
        char temp;
        for(int i=1;i<=9;i++){
          for(int j=1;j<=9;j++){
            scanf("%c",&temp);
            map[i][j]=temp-'0';
            if(map[i][j]){
                row[i][map[i][j]]=1;
                col[j][map[i][j]]=1;
                int k=(i-1)/3*3+(j-1)/3+1;
                grid[k][map[i][j]]=1;
                book[i][j]=1;
            }
         }
         getchar();
        }
        dfs(1,1);
        for(int i=1;i<=9;i++){
            for(int j=1;j<=9;j++)
                printf("%d",map[i][j]);
            putchar('\n');
        }
    }
    return 0;
}

//后来的:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int map[10][10];
int row[10][10],col[10][10],m[10][10];
void print(){
	for(int i = 0;i < 9;i++){
		for(int  j = 0;j < 9;j++){
			printf("%d",map[i][j]);
		}
		putchar('\n');
	}
}
int dfs(int loc){
	if(loc == 81){
		return 1;
	}
	int x = loc / 9,y = loc % 9;
	int cnt = (x / 3) * 3 + y / 3;
	if(map[x][y]){
		return dfs(loc + 1);
	}
	for(int i = 1;i <= 9;i++){
		if(!m[cnt][i] && !row[x][i] && !col[y][i]){
			map[x][y] = i;
			m[cnt][i] = row[x][i] = col[y][i] = 1;
			if(dfs(loc + 1)){
				return 1;
			}
			map[x][y] = 0;//少写这行,调了一小时bug...... 
			m[cnt][i] = row[x][i] = col[y][i] = 0;
		}
	}
	return 0;
}
int main(){
	int n;
	scanf("%d",&n);
	getchar();
	for(int i = 1;i <= n;i++){
		memset(m,0,sizeof(m));
		memset(row,0,sizeof(row));
		memset(col,0,sizeof(col));
		for(int j = 0;j < 9;j++){
			for(int t = 0;t < 9;t++){
				scanf("%c",&map[j][t]);
				map[j][t]-='0';
				int cnt = (j / 3) * 3 + t / 3;
				row[j][map[j][t]] = col[t][map[j][t]] = m[cnt][map[j][t]] = 1;
			}
			getchar();
		}
		dfs(0);
		print();
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值