zoukankan      html  css  js  c++  java
  • poj 3074

    数独问题,暴搜。

    有一个优化,优先搜索可填位置少的

    同时一个位置一个位置填,一次一个位置就好

    可以用二进制储存状态

    #include<cstdio>
    #include<algorithm>
    #define REP(i, a, b) for(register int i = (a); i < (b); i++)
    #define _for(i, a, b) for(register int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXN = 15;
    int r[MAXN], c[MAXN], k[MAXN];
    int lg[1 << 10], num[1 << 10];
    char s[MAXN * MAXN], a[MAXN][MAXN];
    
    inline int ID(int i, int j)
    {
        return 3 * (i / 3) + j / 3;
    }
    
    inline void draw(int x, int y, int z)
    {
        r[x] ^= 1 << z;
        c[y] ^= 1 << z;
        k[ID(x, y)] ^= 1 << z;
    }
    
    bool dfs(int cnt)
    {
        if(cnt == 81) return true;
        int x, y, mint = 10;
        
        REP(i, 0, 9)
            REP(j, 0, 9)
                if(a[i][j] == '.')
                {
                    int val = num[r[i] & c[j] & k[ID(i, j)]];
                    if(!val) return false;
                    if(mint > val)
                    {
                        mint = val;
                        x = i, y = j;
                    }
                }
                
        int tmp = r[x] & c[y] & k[ID(x, y)];
        for(; tmp; tmp -= tmp & (-tmp))
        {
            int t = lg[tmp & (-tmp)];
            a[x][y] = t + '1';
            draw(x, y, t);
            if(dfs(cnt + 1)) return true;
            draw(x, y, t);
            a[x][y] = '.';
        }
        
        return false;
    }
    
    int main()
    {
        REP(i, 0, 9) lg[1 << i] = i;
        REP(i, 0, 1 << 9) 
            for(int j = i; j; j -= j & (-j)) num[i]++;
            
        while(scanf("%s", s) && s[0] != 'e')
        {
            int cnt = 0;
            REP(i, 0, 9) c[i] = r[i] = k[i] = (1 << 9) - 1;
            REP(i, 0, 9)
                REP(j, 0, 9)
                {
                    a[i][j] = s[i * 9 + j];
                    if(a[i][j] != '.') cnt++, draw(i, j, a[i][j] - '1');
                }
                
            dfs(cnt);
            REP(i, 0, 9)
                REP(j, 0, 9)
                    s[i * 9 + j] = a[i][j];    
            puts(s);
        }
        
        return 0;
    }
  • 相关阅读:
    sublime there are no packages for installation
    linux 安装php扩展mbstring
    生成器表达式和列表推导式
    send()和next()
    迭代器生成器
    装饰器
    函数随笔
    Django进阶
    数据结构与算法入门
    MySQL必会
  • 原文地址:https://www.cnblogs.com/sugewud/p/9896178.html
Copyright © 2011-2022 走看看