1026 Sudoku Killer

1026 Sudoku Killer

题意:在一个9x9的方格中,把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成9个3x3的方格也同时包含1-9这九个数字。

思路:记下没有被赋值的位置,然后依次深搜,每次赋值都要判断与原有数据是否冲突,不冲突的话,进行下一个深搜,最后得到结果。

感想:字符的输入,题目要求的判断,很费心,多做多练!

#include<iostream>

#include<math.h>

#include<stdio.h>

#include<string.h>

#include<algorithm>

using namespace std;

char map[10][10];

int pos[90][2];

bool row[10][10],col[10][10];

int t;

bool check(int v,int num){

   int n=pos[v][0]/3*3;  //搜索周围9小格的行的开始搜索位置

   int m=pos[v][1]/3*3;  //搜索周围9小格的列的开始搜索位置

   for(int i=n;i<n+3;++i){

       for(int j=m;j<m+3;++j){

           if(map[i][j]==num+'0') return false;

       }

    }

   return true;

}

bool dfs(int v){

   if(v==t) return true;  //已经把所有节点搜索完了

   for(int i=1;i<10;++i){

       if(!row[pos[v][0]][i]&&!col[pos[v][1]][i]&&check(v,i)){

           map[pos[v][0]][pos[v][1]]=i+'0';

           row[pos[v][0]][i]=true;

           col[pos[v][1]][i]=true;

           if(dfs(v+1)) return true;

           map[pos[v][0]][pos[v][1]]='?';

           row[pos[v][0]][i]=false;

           col[pos[v][1]][i]=false;

           }

    }

   return false;

}

void output(){

   for(int i=0;i<9;++i){

       cout<<map[i][0];

       for(int j=1;j<9;++j){

           cout<<" "<<map[i][j];

       }

       cout<<endl;

    }

   return ;

}

int main(){

   int num=0;

   while(1){

       t=0;

       memset(row,false,sizeof(row));

       memset(col,false,sizeof(col));

       for(int i=0;i<9;i++){

           for(int j=0;j<9;j++){

               if(!(cin>>map[i][j]))exit(0);

                if(map[i][j]=='?'){

                    pos[t][0]=i;

                    pos[t++][1]=j;

                    continue;

                }

                row[i][map[i][j]-'0']=true;

                col[j][map[i][j]-'0']=true;

           }

       }

       dfs(0); //开始搜索第1个问号点

       if(num++)  cout<<endl;

       output();

    }

  return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值