• 数独


    链接

    优化:

    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
  • 相关阅读:
    iOS 程序内国际化的一些心得(2)
    iOS 程序内国际化的一些心得(1)
    写个自己的Xcode4插件
    iOS命令行获取工程内所有的国际化资源并且整合
    用xib自定义UITableViewCell的注意事项——重用问题
    遍历类成员
    iOS 键盘取消晃动撤销动作
    iap验证。
    4 WPF学习---系统的学习XAML语法
    webService访问加密-Soapheader
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/13605068.html
Copyright © 2020-2023  润新知