zoukankan      html  css  js  c++  java
  • 洛谷 P1074【靶形数独】(DFS)

    用三维数组来记录当前这个数字有没有被行或者列或者小九宫格用过,同时优化一下搜索顺序,我们从0少的那一行开始搜索,减小搜索树分支,这个优化是比较大的。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> P;
    P p[100];
    int a[15][15],cnt,ans=-1;
    bool vis[3][15][15];//第一维0表示行 1表示列 2表示9宫格
    int score[10][10]//分数数组
    {
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
        { 0, 6, 7, 7, 7, 7, 7, 7, 7, 6 },
        { 0, 6, 7, 8, 8, 8, 8, 8, 7, 6 },
        { 0, 6, 7, 8, 9, 9, 9, 8, 7, 6 },
        { 0, 6, 7, 8, 9, 10, 9, 8, 7, 6 },
        { 0, 6, 7, 8, 9, 9, 9, 8, 7, 6 },
        { 0, 6, 7, 8, 8, 8, 8, 8, 7, 6 },
        { 0, 6, 7, 7, 7, 7, 7, 7, 7, 6 },
        { 0, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
    };
    struct node{
        int cnt_0, row;
        bool operator<(const node &other)const{
            return cnt_0 < other.cnt_0;
        }
    }r[11];
    int getScore()//得到总分数
    {
        int sum = 0;
        for (int i = 1; i <= 9; i++)
            for (int j = 1; j <= 9; j++)
                sum += a[i][j] * score[i][j];
        return sum;
    }
    int GetGrid(int i, int j)//得到坐标i,j所在的9宫格的编号
    {
        return (i - 1) / 3 * 3 + (j - 1) / 3 + 1;
    }
    void dfs(int k)
    {
        if (k == cnt) {
            ans = max(ans, getScore());
            return;
        }
        int x = p[k].first, y = p[k].second;
        for (int i = 1; i <= 9; i++)
        {
            if (!vis[0][x][i] && !vis[1][y][i] && !vis[2][GetGrid(x, y)][i])//如果未使用
            {
                vis[0][x][i] = vis[1][y][i] = vis[2][GetGrid(x, y)][i] = true;
                a[x][y] = i;
                dfs(k + 1);
                vis[0][x][i] = vis[1][y][i] = vis[2][GetGrid(x, y)][i] = false;//回溯
                a[x][y] = 0;
            }
        }
    }
    int main()
    {
        for (int i = 1; i <= 9; i++)
        {
            int cnt_0 = 0;//记录这一行0的个数
            for (int j = 1; j <= 9; j++)
            {
                scanf("%d", &a[i][j]);
                if (!a[i][j]) cnt_0++;
                else{
                    vis[0][i][a[i][j]] = true;//记录已经使用
                    vis[1][j][a[i][j]] = true;
                    vis[2][GetGrid(i, j)][a[i][j]] = true;
                }
            }
            r[i].row = i, r[i].cnt_0 = cnt_0;
        }
        sort(r + 1, r + 10);//排序,从0少的行开始搜索
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 9; j++)
            {
                int row = r[i].row;
                if (!a[row][j])
                {
                    p[cnt].first =row, p[cnt].second = j;//保存坐标,这就是我们的搜索顺序
                    cnt++;//待填数字的个数
                }
            }
        }
        dfs(0);
        return 0;
    }
  • 相关阅读:
    AI中台
    java的static关键字
    java多线程面试题整理及答案(2019年)
    一篇搞懂TCP的三次握手四次挥手
    异步注解Async
    常用的SQL语句大全
    用Intellij Idea导出可执行的jar包
    用Intellij Idea从Github上获取代码
    Thread线程源码解析,Java线程的状态,线程之间的通信
    dubbo配置启动时检查
  • 原文地址:https://www.cnblogs.com/xiaoguapi/p/10486721.html
Copyright © 2011-2022 走看看