• Acwing-166-数独(搜索)


    链接:

    https://www.acwing.com/problem/content/168/

    题意:

    数独是一种传统益智游戏,你需要把一个9 × 9的数独补充完整,使得图中每行、每列、每个3 × 3的九宫格内数字1~9均恰好出现一次。

    请编写一个程序填写数独。

    思路:

    二进制记录每一行, 每一列, 每一块的数值使用情况, 每次从最小的开始枚举.

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    char input[90];
    char Map[10][10];
    int Cnt[1000], Num[1000];
    int row[10], col[10], gri[10];
    int cnt;
    
    int Lowbit(int x)
    {
        return x&(-x);
    }
    
    int GetP(int x, int y)
    {
        return (x/3)*3+(y/3);
    }
    
    void Change(int x, int y, int p)
    {
        row[x] ^= (1<<p);
        col[y] ^= (1<<p);
        gri[GetP(x, y)] ^= (1<<p);
    }
    
    bool Dfs(int las)
    {
    //    cout << las << endl;
        if (las == 0)
            return true;
        int tmp = 10, x, y;
        for (int i = 0;i < 9;i++)
        {
            for (int j = 0;j < 9;j++)
            {
                if (Map[i][j] != '.')
                    continue;
                int val = row[i]&col[j]&gri[GetP(i, j)];
                if (val == 0)
                    return false;
                if (Cnt[val] < tmp)
                {
                    tmp = Cnt[val];
                    x = i, y = j;
                }
            }
        }
        int val = row[x]&col[y]&gri[GetP(x, y)];
        while (val > 0)
        {
            int z = Num[Lowbit(val)];
            Map[x][y] = z+'1';
            Change(x, y, z);
            if (Dfs(las-1))
                return true;
            Change(x, y, z);
            Map[x][y] = '.';
            val -= Lowbit(val);
        }
        return false;
    }
    
    int main()
    {
        for (int i = 0;i < (1<<9);i++)
        {
            for (int j = i;j > 0;j -= Lowbit(j))
                Cnt[i]++;
        }
        for (int i = 0;i < 9;i++)
            Num[1<<i] = i;
        while (scanf("%s", input) && input[0] != 'e')
        {
            for (int i = 0;i < 9;i++)
            {
                for (int j = 0;j < 9;j++)
                    Map[i][j] = input[i*9+j];
            }
            for (int i = 0;i < 9;i++)
                row[i] = col[i] = gri[i] = (1<<9)-1;
            cnt = 0;
            for (int i = 0;i < 9;i++)
            {
                for (int j = 0;j < 9;j++)
                {
                    if (Map[i][j] != '.')
                        Change(i, j, Map[i][j]-'1');
                    else
                        cnt++;
                }
            }
            Dfs(cnt);
            for (int i = 0;i < 9;i++)
            {
                for (int j = 0;j < 9;j++)
                    input[i*9+j] = Map[i][j];
            }
            puts(input);
        }
    
        return 0;
    }
    
  • 相关阅读:
    防抖和节流
    关于keep-alive的学习
    elementUI上传图片前判断图片的尺寸大小
    vue 判断线上环境还是本地环境
    elementUi table表格的拖拽功能
    获取文件的md5值
    element ui上传腾讯云,更新视频时长
    js音视频文件的时长
    手写一个移动端带惯性的轮播图vue组件
    这个用来总结一些常用的工具函数
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11532465.html
Copyright © 2020-2023  润新知