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;
     }
  • 相关阅读:
    opencv 读写图像文件
    opencv 图像透明
    c# 异步事件
    c++读写文件
    Delphi XE UniGUI UniSession文件下载的方式(SendFile、SendStream )
    Delphi XE UniGUI ExtJS [8] 自定义JavaScript文件调用
    Delphi XE UniGUI ExtJS [7] Delhi 动态添加 ClientEvents.ExtEvents 事件
    Delphi XE UniGUI ExtJS [6] fireEvent 事件 模拟按键点击(JS、ExtJS、Delphi)
    Delphi XE UniGUI ExtJS [5] 鼠标和Key事件
    Delphi XE UniGUI ExtJS [4] Ajax、Response(响应) 的使用
  • 原文地址:https://www.cnblogs.com/hl220284/p/10554432.html
Copyright © 2011-2022 走看看