zoukankan      html  css  js  c++  java
  • 【4】数独(Sudoku Killer)(深度优先遍历)

    问题描述:给你多个数独题目,让你输出答案

    思路:递归确定每一个‘?’的位置的值,直到所有‘?’都被确定。先将原字符数组转换为整型数组,‘?’由数字0代替,然后每一次层递归找到第一个0的位置,如果找到了,找出当前位置所有可以放置的数字,依次尝试,每次假设把这个数放在当前位置,然后再确认下一个0位置的数字,直到数组中找不到0,即是正确结果(递归出口)。

    #include <stdio.h>
    #include <iostream>
    
    using namespace std;
    
     void coutint(int b[9][9])    //输出整型二维数组
     {
         int i,j;
         for(i=0;i<9;i++){
             for(j=0;j<9;j++)
                 if(j!=8)
                     cout<<b[i][j]<<' ';
                 else
                     cout<<b[i][j];
             cout<<endl;
         }
     }
     
     void char2int(char a[9][20],int b[9][9])    //字符二维数组向整型二维数组转换
     {
         int i,j;
         for(i=0;i<9;i++)
             for(j=0;j<18;j++)
                 if(a[i][j]=='?')
                     b[i][j/2] = 0;
                 else if('1'<=a[i][j] && a[i][j]<='9')
                     b[i][j/2] = a[i][j]-'0'; //字符转化为整型
     }
     
     bool judge(int curx,int cury,int num,const int b[9][9])
     {
         int i,j;
         //查找一横行
         for(i=0;i<9;i++)    //将这一行出现的数字全部设为不可填
             if(i!=cury && b[curx][i]==num)
                 return true;
         //查找一竖列
         for(i=0;i<9;i++)    //将这一行出现的数字全部设为不可填
             if(i!=curx && b[i][cury]==num)
                 return true;
         //查找当前九宫格
         int x,y;
         x = curx/3*3;
         y = cury/3*3;
         for(i=0;i<3;i++)
             for(j=0;j<3;j++)
                 if(x+i!=curx && y+j!=cury && b[x+i][y+j]==num)
                     return true;
         return false;
     }
     
     bool dfs(int b[9][9])
     {
         //找到当前第一个'?'位置。如果没有找到,表示所有位置都已填上,即为正确结果,递归结束
         int i,j;
         for(i=0;i<9;i++)
             for(j=0;j<9;j++)
                 if(b[i][j]==0)    //找'?'的位置
                     goto label;            
         label:
         if(i>=9 && j>=9)    //找到正确结果了,递归结束
             return true;
         //记录坐标
         int curx = i,cury = j;
         //确定该位置的可以填的数字
         bool temp[10];    //记录哪些数字可以填
         int num=0;    //记录当前位置可以填的数字的个数
         for(i=1;i<=9;i++)
             if(judge(curx,cury,i,b))    //判断这个位置可不可以放这个数字
                 temp[i] = false;
             else {
                 temp[i] = true;
                 num++;
             }
         if(num==0)
             return false;
         //确定下一个位置
         for(i=1;i<=9;i++)
             if(temp[i]){
                 //这个数在这个位置可以填
                 if(judge(curx,cury,i,b))
                     continue;
                 b[curx][cury] = i;
                 if(dfs(b))
                     return true;
             }
         b[curx][cury] = 0;    //这句千万别忘了写,就是这一步不能走的记得还原为0
         return false;
     }
     int main()
     {
         char a[9][20];
         int b[9][9];
         int i;
         for(i=0;i<9;i++)
             cin.getline(a[i],20,'
    ');
         char2int(a,b);    //char数组转换为int数组
         if(dfs(b))    //产生结果
             coutint(b);    //输出数组内容
     
         while(cin.getline(a[0],20,'
    ')){    //读取空行,或者到文件尾
             cout<<endl;
             char a[9][20];
             int b[9][9];
             int i;
             for(i=0;i<9;i++)
                 cin.getline(a[i],20,'
    ');
             char2int(a,b);    //char数组转换为int数组
             if(dfs(b))    //产生结果
                 coutint(b);    //输出数组内容
         }
         return 0;
     }
  • 相关阅读:
    sabaki and leelazero
    apply current folder view to all folders
    string operation in powershell
    wirte function in powershell
    add environment path to powershell
    Module in powershell
    sql prompt
    vmware中鼠标在部分区域不能使用
    调整多个控件的dock的顺序
    行为型模型 策略模式
  • 原文地址:https://www.cnblogs.com/hl220284/p/10554432.html
Copyright © 2011-2022 走看看