首页 > 编程语言 >牛客[编程题] HJ44 Sudoku数独游戏

牛客[编程题] HJ44 Sudoku数独游戏

时间:2023-11-11 21:23:36浏览次数:40  
标签:Sudoku arr return 牛客 int ++ HJ44 answer line

HJ44 Sudoku 困难  通过率:27.56%  时间限制:1秒  空间限制:32M  

描述

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。 例如: 输入 输出   数据范围:输入一个 9*9 的矩阵

输入描述:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:

完整的9X9盘面数组

示例1

输入:
0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1
输出:
5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1

 

个人感觉,这个题目出的不好,有多种答案,但是题目只给出一种答案;只要不符合标准答案,即使满足要求,也无法通过;6个用例只通过了5个;

后面的Check函数不是为了解出答案,而是为了检查输出的结果;

本方法还有改进的空间,目前无法唯一确定某一个值时,都是从可能的选项中默认选择第一个;

其实如果默认第一个的情况下无法解出答案时,可以用Check+Random的方式,也就是每试一次都是从可能的选项中随机选择一个,如果不行就再来一遍;

前提时要先把能唯一确定的最终状态记录下来,后面开始通过无限循环一直进行查找,总能找到答案;

 using System;
    using System.Collections.Generic;
    public class Program
    {
        public static void Main()
        {
            string line; List<string> lines = new List<string>();
            while ((line = System.Console.ReadLine()) != null)
            { // 注意 while 处理多个 case
                lines.Add(line);

                if (lines.Count == 9)
                {
                    string[] lineArr;
                    int[,] arr = new int[9, 9];
                    int answer = 0; bool find;
                    for (int i = 0; i < 9; i++)
                    {
                        line = lines[i];
                        lineArr = line.Split(" ");
                        for (int j = 0; j < 9; j++)
                        {
                            arr[i, j] = int.Parse(lineArr[j]);
                        }
                    }
                    //最多循环81次
                    for (int k = 0; k < 81; k++)
                    {
                        if (k == 0)
                        {
                            find = true;
                        }
                        else
                        {
                            find = false;
                        }
                        for (int i = 0; i < 9; i++)
                        {
                            for (int j = 0; j < 9; j++)
                            {

                                if (arr[i, j] == 0)
                                {
                                    answer = GetAnswer(i, j, arr, find);
                                    if (answer != 0)
                                    {
                                        arr[i, j] = answer;
                                        find = true;
                                    }

                                }
                            }
                        }
                        //如果已完成,就立即结束循环
                        if (!HasZero(arr))
                        {
                            break;
                        }
                    }
                    
                    //输出
                    for (int i = 0; i < 9; i++)
                    {
                        line = string.Empty;
                        for (int j = 0; j < 9; j++)
                        {
                            line += arr[i, j].ToString();
                            if (j != 8)
                            {
                                line += " ";
                            }
                        }
                        Console.WriteLine(line);
                    }
                    Check(arr);
                }

            }
        }
        //获取某个空位的答案
        static int GetAnswer(int row, int column, int[,] arr, bool find)
        {
            //使用排除法确定可以填写的值
            //一共1-9九个,如果排除到只剩一个,那么就可以确定答案了
            List<int> left = new List<int>();
            for (int i = 1; i <= 9; i++)
            {
                left.Add(i);
            }
            //从行开始排除
            for (int i = 0; i < 9; i++)
            {
                if (i == column) continue;
                left.Remove(arr[row, i]);
            }
            if (left.Count == 1)
            {
                
                return left[0];
            }
            //再从列排除
            for (int i = 0; i < 9; i++)
            {
                if (i == row) continue;
                left.Remove(arr[i, column]);
            }
            if (left.Count == 1)
            {
                return left[0];
            }
            //从所在的九宫格排除
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (row / 3 * 3 + i == row && column / 3 * 3 + j == column)
                        continue;
                    left.Remove(arr[row / 3 * 3 + i, column / 3 * 3 + j]);
                }
            }
            if (left.Count == 1)
            {
                return left[0];
            }
            else if (!find && left.Count > 0)
            {
                return left[0];
            }
            return 0;
        }
        //判定矩阵中是否还有0,也就是判定是否已经完成
        static bool HasZero(int[,] arr)
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (arr[i, j] == 0)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        static bool Check(int[,] arr)
        {
            if (HasZero(arr)) return false;
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    int answer = GetAnswer(i, j, arr, true);
                    if (answer != arr[i, j])
                    {
                        Console.WriteLine($"row={i},col={j},answer={answer},real={arr[i, j]}");
                        return false;
                    }
                }
            }
            return true;
        }
    }

 

标签:Sudoku,arr,return,牛客,int,++,HJ44,answer,line
From: https://www.cnblogs.com/zhangdezhang/p/17826382.html

相关文章

  • 牛客练习赛118
    A.HardKMPProblem#include<bits/stdc++.h>usingnamespacestd;constintN=30;intcnt1[N],cnt2[N];strings,t;voidsolve(){memset(cnt1,0,sizeofcnt1);memset(cnt2,0,sizeofcnt2);cin>>s>>t;for(inti=0;s[i];......
  • 牛客[编程题] HJ32 密码截取
    HJ32密码截取中等  通过率:28.75%  时间限制:1秒  空间限制:32M 描述Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12......
  • 牛客[编程题] HJ69 矩阵乘法
    HJ69矩阵乘法中等  通过率:48.01%  时间限制:1秒  空间限制:32M  描述如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的矩阵的大小不超过100*100输入描述:第一行包含一个正整数x,代......
  • 牛客[编程题] HJ107 求解立方根
    HJ107求解立方根中等  通过率:27.15%  时间限制:1秒  空间限制:32M 描述计算一个浮点数的立方根,不使用库函数。保留一位小数。数据范围:|val|\le20\∣val∣≤20 输入描述:待求解参数,为double类型(一个实数)输出描述:输出参数的立方根。保留一位小数......
  • 牛客[编程题] HJ29 字符串加解密
    HJ29 字符串加解密中等  通过率:25.47%  时间限制:1秒  空间限制:32M 描述对输入的字符串进行加解密,并输出。加密方法为:当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;当内容是数字时则把该数......
  • 牛客[编程题] HJ27 查找兄弟单词
    HJ27 查找兄弟单词  描述定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。兄弟单词要求和原来的单词不同。例如:ab和ba是兄弟单词。ab和ab则不是兄弟单词。现在给定你n个单词,另外再......
  • 牛客[编程题] HJ26 字符串排序
    HJ26 字符串排序  中等  通过率:39.52%  时间限制:1秒  空间限制:32M 描述编写一个程序,将输入字符串中的字符按如下规则排序。规则1:英文字母从A到Z排列,不区分大小写。如,输入:Type输出:epTy规则2:同一个英文字母的大小写同时存在时,按照输入......
  • 牛客[编程题] HJ25 数据分类处理
     描述信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。  数据范围:1\leI,R\le100\1≤I,R≤100  ,输入的整数大小满足 0\lev......
  • 牛客[编程题]坐标移动
     https://www.nowcoder.com/questionTerminal/119bcca3befb405fbe58abe9c532eb29publicclassProgram{publicstaticvoidMain(){stringline;while((line=System.Console.ReadLine())!=null){//注意while处理多个casestr......
  • 牛客小白月赛80C/D又放学辣
    C这么小的数据范围,想必胡搞就可以了。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>usingnamespacestd;intn,m,k;structcll{intp;intid;}cl[105];intx;intans[205];boolcmp(cllx,clly){returnx.p......