zoukankan      html  css  js  c++  java
  • 数独

    链接

    优化:

    1 唯一确定的数字

    2 空的格子少的

     int minv = 10,minx = -1,miny = -1;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(s[i * 9 + j] == '.'){
                    int c = ones[get(i,j)];
                    if(c < minv){
                        minv = c;
                        minx = i;miny = j;
                    }
                }
            }
        }
    View Code

    r,c,分别记录行和列的数字

    cel记录每个九宫格里面的数字

    最初都假设为1,表示可选数字,

    i 1 << i 1 << i - 1
    0 1 0
    1 10 1
    2 100 11
    3 1000 111
    4 10000 1111
    5 100000 11111
    6 1000000 111111
    7 10000000 1111111
    8 100000000 11111111
    ....    
         

    000000001表示可填1

    000000101表示3 和 1可填

    如果字符串s中出现了数字,那么当前行列九宫格里面的这个数字变为0,

    mp来映射 mp[1 << i] = i;

    ones[i]表示i里面有几个1

    #include <bits/stdc++.h>
    using namespace std;
    const int n = 9;
    const int maxn = 1 << n;
    int r[n],c[n],cel[n/3][n/3];//行 列 九宫格
    char s[110];
    int ones[maxn];//每个数字里面包含的1的个数,1等价 1,2等价 10,3等价11
    int mp[maxn];//数字对应关系
    inline int lowbit(int x){
        return x & -x;
    }
    inline int get(int x,int y){
        return r[x] & c[y] & cel[x/3][y/3];
    }
    int dfs(int cnt,char s[]){
        if(!cnt) return 1;//数字都填好了
        int minv = 10,minx = -1,miny = -1;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(s[i * 9 + j] == '.'){
                    int c = ones[get(i,j)];
                    if(c < minv){
                        minv = c;
                        minx = i;miny = j;
                    }
                }
            }
        }
        if(!minv) return 0;//又要修改的点,但是为0
        int trynums = get(minx,miny);
         while(trynums){
             int trynum = mp[lowbit(trynums)];
             r[minx] -= 1 << trynum;
             c[miny] -= 1 << trynum;
             cel[minx/3][miny/3] -= 1 << trynum;
             s[minx * 9 + miny] = '1' + trynum;
             if(dfs(cnt - 1,s)) return 1;
             r[minx] += 1 << trynum;
             c[miny] += 1 << trynum;
             cel[minx/3][miny/3] += 1 << trynum;
             s[minx * 9 + miny] = '.' ;
             trynums -= lowbit(trynums);
         }
        return 0;
    }
    void init(){
        for(int i = 0; i < n; i++){
            r[i] = c[i] = (1 << n) - 1;//每行每列都先标记为1
            mp[1 << i] = i;
        }
        //每个九宫格的标记
        for(int i = 0; i < n / 3; i++) {
            for (int j = 0; j < n / 3; j++){
                cel[ i ][ j ] = (1 << n) - 1;
            }
        }
    }
    int main(){
        //freopen("in","r",stdin);
        ios::sync_with_stdio(0);
        //每个数字里面1的个数
        for(int i = 0; i < 1 << n; i++)
            for(int j = i; j;j -= lowbit(j))
                  ones[i]++;
    
        while(cin >> s && s[0] != 'e'){
            //cout << s << endl;
            init();
            int cnt = 0;
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    if(s[i * 9 + j] != '.'){//表示已经有数字了
                         int num = 1 << (s[i * 9 + j] - '1');
                         r[i] -= num;c[j] -= num;
                         cel[i / 3][j / 3] -= num;
                    }else cnt++;
                }
            }
            dfs(cnt,s);
            cout << s << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    借助magicwindow sdk plugin快速集成sdk
    Deeplink做不出效果,那是你不会玩!
    iOS/Android 浏览器(h5)及微信中唤起本地APP
    C#回顾 Ado.Net C#连接数据库进行增、删、改、查
    C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录 修改文件名、文件夹名
    C#中的静态方法|如何调用静态方法
    SpringBoot实体类对象和json格式的转化
    SpringBoot + kaptcha 生成、校对 验证码
    SpringBoot配置自定义美化Swagger2
    Spring Boot关于layui的通用返回类
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/13605068.html
Copyright © 2011-2022 走看看