• 【洛谷】P1784 数独


    最近学校搞了个数独比赛,于是找了这道题。

    题目描述

    数独是根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

    芬兰一位数学家号称设计出全球最难的“数独游戏”,并刊登在报纸上,让大家去挑战。

    这位数学家说,他相信只有“智慧最顶尖”的人才有可能破解这个“数独之谜”。

    据介绍,目前数独游戏的难度的等级有一道五级,一是入门等级,五则比较难。不过这位数学家说,他所设计的数独游戏难度等级是十一,可以说是所以数独游戏中,难度最高的等级他还表示,他目前还没遇到解不出来的数独游戏,因此他认为“最具挑战性”的数独游戏并没有出现。

    输入输出格式

    输入格式:

    一个未填的数独

    输出格式:

    填好的数独

    输入输出样例

    输入样例#1:

    8 0 0 0 0 0 0 0 0
    0 0 3 6 0 0 0 0 0
    0 7 0 0 9 0 2 0 0
    0 5 0 0 0 7 0 0 0
    0 0 0 0 4 5 7 0 0
    0 0 0 1 0 0 0 3 0
    0 0 1 0 0 0 0 6 8
    0 0 8 5 0 0 0 1 0
    0 9 0 0 0 0 4 0 0

    输出样例#1:

    8 1 2 7 5 3 6 4 9
    9 4 3 6 8 2 1 7 5
    6 7 5 4 9 1 2 8 3
    1 5 4 2 3 7 8 9 6
    3 6 9 8 4 5 7 2 1
    2 8 7 1 6 9 5 3 4
    5 2 1 9 7 4 3 6 8
    4 3 8 5 2 6 9 1 7
    7 9 6 3 1 8 4 5 2

     

    题解:

    这是一道深度优先搜索题,obviously!!

    只要开3个BOOL数组,hang[i][j](第i行是否出现过数j),lie[i][j](第i列是否出现过数j),kuai[i][j](第i块是否出现过数j)。

    其中你要自己推一个(x,y)属于哪一块的公式:  f(x,y) = (x-1)/3*3+ceil(y/3.0) 或者 f(x,y) = (x-1)/3*3+(y-1)/3+1   (从左往右,从上向下数)

    所以这道题的标程就很简单了:

    #include<bits/stdc++.h>
    using namespace std;
    int Map[15][15];
    bool hang[10][10],lie[10][10],kuai[10][10],f = 0;
    
    void print()
    {
    	for (int i = 1 ; i <= 9 ; i++)
    	{
    		 for (int j = 1 ; j <= 8 ; j ++) printf("%d ",Map[i][j]);
    		 cout<<Map[i][9]<<endl;
    	}	    
    }
    
    void dfs(int x,int y)
    {
    	if (Map[x][y] != 0)
    	{
    		if (x == 9 && y == 9)  {
    			print();
    			f = 1;
    			return;
    		}
    		if (y == 9) dfs(x+1,1); else dfs(x,y+1);
    	}
    	if (Map[x][y] == 0)
    	for (int i = 1 ; i <= 9 ; i ++)
    	{
    		if (hang[x][i] && lie[y][i] && kuai[(x-1)/3*3+(y-1)/3+1][i])
    		{
    			Map[x][y] = i; int k = (x-1)/3*3+(y-1)/3+1;
    			hang[x][i] = 0;
    			lie[y][i] = 0;
    			kuai[k][i] = 0;
    			if (x == 9 && y == 9)  {
    				print();
    				f = 1;
    				return;
    			}
    			if (y == 9) dfs(x+1,1); else dfs(x,y+1);
    			if (f) return;
    			Map[x][y] = 0; 
    			hang[x][i] = 1;
    			lie[y][i] = 1;
    			kuai[k][i] = 1;
    		}
    	}
    }
    
    int main()
    {
    	memset(hang,true,sizeof(hang));
    	memset(lie,true,sizeof(lie));
    	memset(kuai,true,sizeof(kuai));
    	for (int i = 1 ; i <= 9 ; i ++)
    	  for (int j = 1 ; j <= 9 ; j ++)
    	  	{
    			scanf("%d",&Map[i][j]);
    			if (Map[i][j] > 0)
    			{
    				int k = (i-1)/3*3+(j-1)/3+1;
    				hang[i][Map[i][j]] = 0;                   
    				lie[j][Map[i][j]] = 0;     			   
    				kuai[k][Map[i][j]] = 0;					   
    			} 
    		}
    	dfs(1,1);
    	return 0;
    }
    

      

     

  • 相关阅读:
    最大连续序列和
    打印有序链表的公共部分
    字符串最长子串大小
    jvm简介
    大浮点数乘法
    java代码的快速排序理解
    从内存分配分析程序初始化和存储
    时间复杂度
    Filter&Listener
    MVC开发模式&EL表达式&JSTL&三层架构开发
  • 原文地址:https://www.cnblogs.com/YMY666/p/8178330.html
Copyright © 2020-2023  润新知