首页 > 其他分享 >洛谷P1784.数独

洛谷P1784.数独

时间:2024-11-13 13:07:44浏览次数:1  
标签:std 10 arr 洛谷 mat int 九宫格 P1784 数独

P1784数独

思路

这个题目最麻烦的是如何判断

我们需要判断每一行每一列每一个九宫格

这里有个小技巧,把每一行,每一列,每一个九宫格哪个数有没有被用过用数组存起来 哪个数字属于哪个九宫格也可以先先存起来

int id[10][10] = {{0,0,0,0,0,0,0,0,0,0},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9}};
// id[i][j] (i, j)这个位置的元素属于哪个格子
bool row[10][10]; // row[i][j] 第i行j这个数有没有被用过
bool line[10][10]; // line[i][j] 第i列j这个数有没有被用过
bool sub[10][10]; // sub[i][j] 第i个格子j这个数有没有被用过

然后我们将每一个空格的位置记录下来,\(dfs\)每一个空格的位置就好了

代码

#include <bits/stdc++.h>
#define endl '\n'
//#define int long long
const int maxn = 2e5 + 5;
const int inf = 1e18;

struct custom_hash 
{
	static uint64_t splitmix64(uint64_t x) 
    {
		x ^= x << 13;
		x ^= x >> 7;
		x ^= x << 17;
		return x; 
	}
	size_t operator () (uint64_t x) const 
    {
		static const uint64_t FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count(); // 时间戳
		return splitmix64(x + FIXED_RANDOM);
	}
};

struct Empty
{
    int x, y;
}arr[100];

int id[10][10] = {{0,0,0,0,0,0,0,0,0,0},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9}};
// id[i][j] (i, j)这个位置的元素属于哪个格子
int cnt = 0;
int mat[10][10];
bool row[10][10]; // row[i][j] 第i行j这个数有没有被用过
bool line[10][10]; // line[i][j] 第i列j这个数有没有被用过
bool sub[10][10]; // sub[i][j] 第i个格子j这个数有没有被用过
bool ifexit = false;
// 打印矩阵
void print()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            std::cout << mat[i][j] << " ";
        }
        std::cout << endl;
    }
}

void dfs(int c)
{
    if (ifexit) return;
    if (c > cnt)
    {
        print();
        ifexit = true;
        return;
    }
    int xx = arr[c].x, yy = arr[c].y;
    for (int i = 1; i <= 9; i++)
    {
        if (row[xx][i] == 0 && line[yy][i] == 0 && sub[id[xx][yy]][i] == 0)
        {
            mat[xx][yy] = i;
            row[xx][i] = 1;
            line[yy][i] = 1;
            sub[id[xx][yy]][i] = 1;
            dfs(c + 1);
            mat[xx][yy] = 0;
            row[xx][i] = 0;
            line[yy][i] = 0;
            sub[id[xx][yy]][i] = 0;
        }
    }
}

void solve()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            std::cin >> mat[i][j];
            if (mat[i][j] == 0)
            {
                arr[++cnt].x = i;
                arr[cnt].y = j;
            }
            else
            {
                row[i][mat[i][j]] = 1;
                line[j][mat[i][j]] = 1;
                sub[id[i][j]][mat[i][j]] = 1;
            }
        }
    }
    dfs(1);
}

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); std::cout.tie(nullptr);
    //freopen("out.txt", "w", stdout);
    int t = 1;
    //std::cin >> t;
    while(t--)
    {
        solve();
    }
    return 0;
}

标签:std,10,arr,洛谷,mat,int,九宫格,P1784,数独
From: https://www.cnblogs.com/SteinsGateSg/p/18543695

相关文章

  • 洛谷题单指南-二叉堆与树状数组-P1878 舞蹈课
    原题链接:https://www.luogu.com.cn/problem/P1878题意解读:n个男女排列一行,每人舞蹈技术是ai,每次找到相邻男女舞蹈技术差值绝对值最小的一对出列,输出每对出列的人员编号。解题思路:设初始有8人编号为:12345678将12,23,34,45,56,67,78中是男女的配对编号以及a......
  • 洛谷P3654
    P3654FirstStep(ファーストステップ)-洛谷|计算机科学教育新生态FirstStep(ファーストステップ)题目背景我们Aqours,要第一次举办演唱会啦!虽然学生会长看上去不怎么支持我们的样子,可是有了理事长的支持,我们还是被允许在校内的篮球场里歌唱!歌曲也好好地准备过了,名......
  • 【题解】洛谷P7287: 「EZEC-5」魔法
    P7287「EZEC-5」魔法感觉好题有思维,但是我没认真读题,看到样例就我以为了,他让任意一个区间满足大于\(S\)即可不是全部。我们手搓一下样例就可以发现,对于加法我们不加白不加的话肯定全部的数都加上,乘法肯定要等到加完后才开始,这些都是贪心思路。然后就是开始搭配操作了,我遇到......
  • 【题解】洛谷P7286:「EZEC-5」人赢
    P7286「EZEC-5」人赢可以想到对于每个数要找到比他大的数中下标最大的数,我们按照数的大小排序,我们维护原序列的一个指针,对于每个数如果比指针大那么就左移指针,可以思考下为什么:指针上的数比现在这个数要小那比后面的数都小,于是我们左移指针直到大于这个数,可以发现我们也在一直......
  • 洛谷 P1772 [ZJOI2006] 物流运输 做题记录
    很神经的一道题。令\(val_{i,j}\)表示从第\(i\)天到第\(j\)天每天都走一条道路,单次的最小花费。可以枚举\(\{i,j\}\)然后把在这个区间里的所有点设置成不可达,每一个\(\{i,j\}\)都可以用floyd算,时间复杂度\(O(n^2m^3)\)。令\(f_i\)表示第\(i\)天的最小花费,那么......
  • 洛谷解题日记||基础篇4
     #include<iostream>usingnamespacestd;intmain(){intn,m;cin>>n>>m;//计算所有矩形的数量longlongtotalRectangles=(longlong)(n*(n+1)/2)*(longlong)(m*(m+1)/2);//计算正方形的数量longlongt......
  • 【题解】洛谷P8346:最澄澈的空与海
    【题解】洛谷P8346:最澄澈的空与海猜结论题,本身其实很简单,在纸上画个差不多就能想出来,我一开始想二分图最大匹配,但是还是太大了,不可以。当一个二分图有且仅有一种解时,必定有节点的入度为\(1\)。我们想到有多种匹配的情况,可以想到如果这是一个环的情况,一个左边的点将他右边的点......
  • 题解:洛谷 P5180 【模板】支配树
    在图论模拟赛被T4的有向图必经点硬控了\(10^9+7s\),写篇题解纪念一下。其实,求有向图的必经点,通法就是支配树。一些定义:支配点:在确定起点\(S\)的情况下,对于一个点\(k\),若存在\(x\),使得删除\(x\)以及与\(x\)连接的边后,\(x\)与\(k\),不再强连通,那么就称\(k\)为\(x......
  • 【题解】洛谷P3118: Moovie Mooving G
    洛谷P3118:MoovieMoovingG看到数据范围考虑状压,题目要求看的电影最少那就维护时间最大,我们设\(f_{i}\)为\(i\)状态最多可以看多久的电影,对于不在集合的点我们枚举转移。我们每个开始时间都对应一个截至时间,问能加入这个点,每个点花费时间是固定的,我们又要不间断所以我们找......
  • 洛谷P5744
    P5744【深基7.习9】培训-洛谷|计算机科学教育新生态【深基7.习9】培训题目描述某培训机构的学员有如下信息:-姓名(字符串)-年龄(周岁,整数)-去年NOIP成绩(整数,且保证是5 的倍数)经过为期一年的培训,所有同学的成绩都有所提高,提升了20%(当然NOIP满分是600 分,不能......