• 数独 题解


    来自算法竞赛进阶指南

    一道思路很好想,特别难写的题。

    主要运用搜索可行性剪枝,二进制位运算优化。

    没有什么难度,就是模拟。但是难写。

    发一下来纪念我写了二十分钟。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    const int N = 9,M = 1 << N;
    int ones[M],map[M];
    int row[N],col[N],cell[3][3];
    
    char str[100];
    
    void init()
    {
        for(int i = 0; i < N; ++ i) row[i] = col[i] = (1 << N) - 1;
        for(int i = 0; i < 3; ++ i)
          for(int j = 0; j < 3; ++ j)
            cell[i][j] = (1 << N) - 1;
    }
    
    void draw(int x,int y,int t,bool is_set)
    {
        if(is_set) str[x * N + y] = '1' + t;
        else str[x * N + y] = '.';
        
        int v = 1 << t;
        if(!is_set) v = -v;
        row[x] -= v;
        col[y] -= v;
        cell[x / 3][y / 3] -= v;
    }
    int lowbit(int x)
    {
        return x & -x;
    }
    int get(int x,int y)
    {
      return row[x] & col[y] & cell[x / 3][y / 3];
    
    }
    
    
    bool dfs(int cnt)
    {
        if(!cnt) return true;
        int minv = 10;
        int x,y;
        for(int i = 0; i < N; ++ i)
          for(int j = 0; j < N; ++ j)
          if(str[i * N + j] == '.')
            {
                int state = get(i,j);
                if(ones[state] < minv)
                {
                    minv =ones[state];
                    x = i,y = j;
                }
            }
        int state = get(x,y);
        for(int i = state;i ; i -= lowbit(i))
        {
            int t = map[lowbit(i)];
            draw(x,y,t,true);
            if(dfs(cnt - 1)) return true;
            draw(x,y,t,false);
        }
        return false;
    }
    
    int main()
    {
        for(int i = 0; i < N; ++ i) map[1 << i] = i;
        for(int i = 0; i < 1 << N; ++ i)
          for(int j = 0; j < N; ++ j)
            ones[i] += i >> j & 1;
        while(cin >> str,str[0] != 'e')
        {
            init();
            int cnt = 0;
            for(int i = 0,k = 0; i < 9; ++ i)
             for(int j = 0; j < 9; ++ j, ++ k)
               if(str[k] != '.')
               {
                   int t = str[k] - '1';
                   draw(i,j,t,true);
               }
               else cnt ++;
            dfs(cnt);
            puts(str);
        }
    }
  • 相关阅读:
    微信小程序地图组件中的include-points怎样缩放视野并将所有坐标点在规定的视野内展示?
    两种常见的mysql集群架构
    layui+oss阿里云附件上传回调报错问题
    redis hash过期时间
    Static和Extern关键字理解
    代理模式
    中介者模式
    访问者模式
    模板方法模式
    迭代器模式
  • 原文地址:https://www.cnblogs.com/yjyl0098/p/15144308.html
Copyright © 2020-2023  润新知