zoukankan      html  css  js  c++  java
  • 【算法学习笔记】61.回溯法 DFS SJTU OJ 1106 sudoku

    虽然DLX可以提高效率....但是对于NPC问题也不用太追求效率了,而且还只有一个测试点。

    所以 只要DFS不断的填入,直到空格全部被填满;要注意的是DFS中全局变量的更新和恢复。

    至于存储的方法,只要考虑每一行每一列每一个小块的不重复即可。

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int cnt = 0 ;//表示剩余的要填的空格的数目
    
    struct point
    {
        int x,y;
    };
    
    point epts[81+5];//存储空格
    
    bool r[10][10], //r[i][k]表示在第i行是否有k这个数字
    c[10][10], //c[j][k]表示在第j列是否有k这个数字
    sq[4][4][10];//sq[t][t][k]表示在第t,t这个小块里 是否有k这个数字
    
    int G[10][10];//存储整个输入的数独 其实没有必要
    
    int ans = 0;
    
    void dfs(int cur){
        if(ans > 1)
            return;
        if(cur < 0) {//如果全部的空格都填满了
            bool ok = true;
            //一定要判断合法性...
            for (int i = 0; i < 9; ++i){
                for (int j=1; j <= 9; ++j){
                    if( (!r[i][j]) || (!c[i][j]) || (!sq[i/3][i/3][j]))
                        ok = false;
                }
            }
            if(ok)
                ans++;
            return;
        }
        int x = epts[cur].x;
        int y = epts[cur].y;
        
        for (int k = 1; k <= 9; ++k)
        {
            if(r[x][k] || c[y][k] || sq[x/3][y/3][k])
                continue;
            r[x][k] = c[y][k] = sq[x/3][y/3][k] = true;//设置存入
            //G[x][y] = k;
            dfs(cur-1);
            r[x][k] = c[y][k] = sq[x/3][y/3][k] = false;//取消存入
        }
        
        return;
    }
    
    
    int main(int argc, char const *argv[])
    {
        int T;
        cin>>T;
        for (int t = 0; t < T; ++t)
        {
            cnt = 0;//初始化
            ans = 0;
            memset(r,false,sizeof(r));
            memset(c,false,sizeof(c));
            memset(sq,false,sizeof(sq));
            
            for (int i = 0; i < 9; ++i){
                for (int j=0; j < 9; ++j){
                    int k;
                    cin>>k;
                    G[i][j] = k;
                    if(k>0)
                        r[i][k] = c[j][k] = sq[i/3][j/3][k] = true;
                    else
                        epts[cnt++] = (point){i,j}; //生成对象
                }
            }
            
            
            //从最后一个空格开始dfs 试图填满
            dfs(cnt-1);
            
            if(ans==1){ 
                cout<<"Yes"<<endl;
            }
            else
                cout<<"No"<<endl;
        }
        return 0;
    }
     
  • 相关阅读:
    第22章 算法
    第二十一章 数据结构
    mysql 索引
    MySQL 视图
    MySQL 子查询
    MySQL 批量更新数据
    MySQL 默认值
    Spring 整体架构和环境搭建
    python之字符串
    python学习
  • 原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1106.html
Copyright © 2011-2022 走看看