zoukankan      html  css  js  c++  java
  • 插播一条 关于数独的解法记录

    首先应该知道了。https://ac.nowcoder.com/acm/contest/625/E

    这个数字必须是行,列,3X3小方块区域内,有且出现过一次的数字。

    代码标记为

    row[i][x] = 1 表示行出现过
    col[j][x] = 1 表示列出现过

    对于3X3的区域来说。有两种记录方式

    tab[i/3][j/3][t]=1 最好理解,表示9个方块中某一个出现x,就标记为1
    对应的。把 i/3和j/3给挪出来,同样可以对应一个方块
    i/3 * 3 + j/3

    然后就是简单的把数字给记录在数组里面

    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            cin>>arr[i][j];
            int ans = arr[i][j];
            if(ans){
                int miarea = arrnum(i,j);
                row[i][ans]=1;
                col[j][ans]=1;
                area[miarea][ans]=1;
            }else{
                num++;
                Ve.push_back(make_pair(i,j));
            }
        }
    }

    接下来,判断是否符合条件

    int arrnum(int i,int j){
        return i/3*3+j/3;
    }
    bool check(int i,int j,int k){
      int t = arrnum(i,j);
      if(row[i][k]||col[j][k]||area[t][k]) return 0;
      return 1;
    }

    然后dfs一下

    bool dfs(int sum){
        if(sum == num){
            return true;
        }
        for(int i = 1;i<=9;i++){
            int x = Ve[sum].first;
            int y = Ve[sum].second;
            int miarea = arrnum(x,y);
            //cout<<x<<" "<<y<<" "<<miarea<<" "<<check(x,y,i)<<endl;
            if(check(x,y,i)){
                row[x][i]=1;
                col[y][i]=1;
                area[miarea][i]=1;
                arr[x][y]=i;
    
                if(dfs(sum+1)){
                    return true;
                }
                row[x][i]=0;
                col[y][i]=0;
                area[miarea][i]=0;
                arr[x][y]=0;
            }
        }
    
        return false;
    }

    最后是完整的代码

    #include<bits/stdc++.h>
    using namespace std;
    vector<pair<int,int>>Ve;
    int arr[10][10],num;
    bool row[10][10],col[10][10],area[10][10],flag;
    int arrnum(int i,int j){
        return i/3*3+j/3;
    }
    bool check(int i,int j,int k){
      int t = arrnum(i,j);
      if(row[i][k]||col[j][k]||area[t][k]) return 0;
      return 1;
    }
    bool dfs(int sum){
        if(sum == num){
            return true;
        }
        for(int i = 1;i<=9;i++){
            int x = Ve[sum].first;
            int y = Ve[sum].second;
            int miarea = arrnum(x,y);
            //cout<<x<<" "<<y<<" "<<miarea<<" "<<check(x,y,i)<<endl;
            if(check(x,y,i)){
                row[x][i]=1;
                col[y][i]=1;
                area[miarea][i]=1;
                arr[x][y]=i;
    
                if(dfs(sum+1)){
                    return true;
                }
                row[x][i]=0;
                col[y][i]=0;
                area[miarea][i]=0;
                arr[x][y]=0;
            }
        }
    
        return false;
    }
    int main(){
        int n;
        memset(col,0,sizeof(col));
        memset(row,0,sizeof(row));
        memset(area,0,sizeof(area));
        num = 0;
    
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                cin>>arr[i][j];
                int ans = arr[i][j];
                if(ans){
                    int miarea = arrnum(i,j);
                    row[i][ans]=1;
                    col[j][ans]=1;
                    area[miarea][ans]=1;
                }else{
                    num++;
                    Ve.push_back(make_pair(i,j));
                }
            }
        }
    
        dfs(0);
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if(j!=8){
                    cout<<arr[i][j]<<" ";
                }else{
                    cout<<arr[i][j]<<endl;
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    分时段查询数据
    优秀产品经理的7大核心技能
    控制台打印螺旋数组
    强大的jquery,再次让我为之鼓掌——三维展示插件
    立象条码打印机PPLB类单双标签打印
    一次与德国程序员的交流
    用ASP为Discuz扩展点小功能
    GDI+ 小破孩动画
    回应YeanJay同学jQuery按钮改变DIV背景色
    C# Dock Style 设置
  • 原文地址:https://www.cnblogs.com/yinghualuowu/p/11437673.html
Copyright © 2011-2022 走看看