【基础搜索】poj-2676-Sudoku(数独)--求补全九宫格的一种合理方案

 

数独

时限:2000 MS   内存限制:65536K
提交材料共计: 22682   接受: 10675   特别法官

描述

数独是一个非常简单的任务。一个9行9列的正方形表被分成9个较小的3x3,如图所示。在一些单元格中,从1写到9的十进制数字。其他细胞是空的。目标是用从1到9的十进制数字填充空单元格,每个单元格有一个数字,这样在每一行、每列和每个标记为3x3的子方格中,将出现从1到9的所有数字。编写一个程序来解决给定的数独任务.

输入

输入数据将从测试用例的数量开始。对于每个测试用例,后面有9行,对应于表的行。在每一行上都会给出一个精确的9位小数字符串,对应于这一行中的单元格。如果单元格为空,则由0表示。

输出量

对于每个测试用例,您的程序应该以与输入数据相同的格式打印解决方案。空的单元格必须按照规则填充。如果解决方案不是唯一的,那么程序可以打印其中的任何一个。

样本输入

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

样本输出

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127

来源


大致题意和思路:

  题目中的部分点是固定的,需要在第一遍读入中处理完;接着进行依次深度优先搜索,每枚举一位,要判断是否与当前行冲突或者当前列冲突,或者是否当前所在的小格子里的冲突了;如果都没有那么当前状态就达到了“稳定”,接着迭代搜索下一位,直到完成即可!

  搜索的时候,会遇见三种情况,上面是第一种,第二种是遇见固定的直接跳到下一位,如果下一位(x,y)的y是10的话,就可以达到巧妙换行的要求了。


题解:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<set>
#include<string.h>
#include<string>
#include<map>
#include<queue>
using namespace std;

#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f

int a[10][10];//从(1,1)一直存到(9,9)
bool vis[10][10];
bool Fixed[10][10];//当前位置是否可以已经固定了!
bool grid[10][10];//1--9的大方格的1--9的使用了1/0次
bool row[10][10];//横行
bool col[10][10];//
int flag;
int getnum(int i,int j){//返回(i,j)所在的小九宫格的序号
    if(i>=1&&i<=3&&j>=1&&j<=3)return 1;
    if(i>=1&&i<=3&&j>=4&&j<=6)return 2;
    if(i>=1&&i<=3&&j>=7&&j<=9)return 3;

    if(i>=4&&i<=6&&j>=1&&j<=3)return 4;
    if(i>=4&&i<=6&&j>=4&&j<=6)return 5;
    if(i>=4&&i<=6&&j>=7&&j<=9)return 6;

    if(i>=7&&i<=9&&j>=1&&j<=3)return 7;
    if(i>=7&&i<=9&&j>=4&&j<=6)return 8;
    if(i>=7&&i<=9&&j>=7&&j<=9)return 9;
}

void init(){
    memset(Fixed,false,sizeof(Fixed));
    memset(a,0,sizeof(a));
    memset(vis,false,sizeof(false));
    memset(grid,false,sizeof(grid));
    flag=0;
    memset(row,false,sizeof(row));
    memset(col,false,sizeof(col));

}

void dfs(int i,int j){
    if(flag==1)return ;
    if(i==9&&j==10){
        for(int i=1;i<=9;i++){
            for(int j=1;j<=9;j++){
                printf("%d",a[i][j]);
            }
            cout<<endl;
        }
        flag=1;
        return ;
    }
    if(j==10)
        dfs(i+1,1);
    else if(Fixed[i][j]==true)
        dfs(i,j+1);
    else{
        int num;
        for(num=1;num<=9;num++){
            if(flag==1)return ;
            if(grid[getnum(i,j)][num]==true)continue;
            if(row[i][num]==true)continue;
            if(col[j][num]==true)continue;

            a[i][j]=num;//记录结果!!
            grid[getnum(i,j)][num]=true;
            row[i][num]=true;col[j][num]=true;
            dfs(i,j+1);
            row[i][num]=false;col[j][num]=false;
            grid[getnum(i,j)][num]=false;
        }
    }

}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        int x;
        for(int i=1;i<=9;i++){
            for(int j=1;j<=9;j++){
                scanf("%1d",&x);
                if(x!=0){
                    a[i][j]=x;
                    Fixed[i][j]=true;
                    grid[getnum(i,j)][x]=1;
                    row[i][x]=1;
                    col[j][x]=1;
                }
            }
        }
        dfs(1,1);
    }

    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/zhazhaacmer/p/9034552.html