蓝桥杯校内选拔赛/POJ 数独(深搜)

Sudoku

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 14530   Accepted: 7178   Special Judge

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task. 

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127

Source

Southeastern Europe 2005

搜索时要对行,列,每个小数独阵进行判断,判断该数字是否在这三个中出现过,是否出现用标识符标记,处理时i,j从下标0开始,处理行标,列标比较方便。思路较简单,看代码吧。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define MAXN 12
 5 using namespace std;
 6 int num[MAXN][MAXN];
 7 int row[MAXN][MAXN];//用来标记每一行九个数是否已被使用,使用记为1
 8 int col[MAXN][MAXN];//列
 9 int mar[MAXN][MAXN];//用0-8标识9个小数独矩阵
10 char chr[MAXN][MAXN];
11 bool flag=false;
12 void dfs(int m,int n)
13 {
14     int s,i,j;
15
16     if(m==9&&n==0)
17     {
18         for(i=0;i<=8;i++)
19         {
20             for(j=0;j<=8;j++)
21             {
22                 cout<<num[i][j];
23             }
24             cout<<endl;
25         }
26         flag=true;
27     }
28     else
29     {
30         if(num[m][n]!=0)
31         {
32             if(n<=7)
33                 dfs(m,n+1);
34             else
35                 dfs(m+1,0);
36         }
37         else
38         {
39             for(i=1;i<=9;i++)
40         {
41             if(row[m][i]==0&&col[n][i]==0&&mar[m/3*3+n/3][i]==0)//根据i,j标定它所属的行,列,和所在的小矩阵
42             {
43                 s=m/3*3+n/3;
44                 num[m][n]=i;
45                 row[m][i]=1;
46                 col[n][i]=1;
47                 mar[s][i]=1;
48                 if(n<=7)
49                     dfs(m,n+1);
50                 else
51                     dfs(m+1,0);
52                 if(flag)
53                     return ;
54                 num[m][n]=0;//一旦回溯过来,必须重新置0,因为说明此数字对于后面的搜索产生了不满足,故将其置0.
55                 row[m][i]=0;
56                 col[n][i]=0;
57                 mar[s][i]=0;
58             }
59         }
60         }
61     }
62 }
63 int main()
64 {
65     //freopen("data.in","r",stdin);
66    // freopen("data.out","w",stdout);
67     int i,j,s,t;
68     cin>>t;
69     while(t--)
70     {
71         memset(row,0,sizeof(row));
72         memset(col,0,sizeof(col));
73         memset(mar,0,sizeof(mar));
74         for(i=0;i<9;i++)
75             scanf("%s",chr[i]);
76         for(i=0;i<9;i++)
77             for(j=0;j<9;j++)
78         {
79             num[i][j]=chr[i][j]-‘0‘;
80             s=num[i][j];
81             if(s!=0)
82             {
83                 row[i][s]=1;
84                 col[j][s]=1;
85                 mar[i/3*3+j/3][s]=1;//初始,一旦有数字,则要将它所在的行列及小矩阵标为1
86             }
87         }
88         flag=false;
89         dfs(0,0);
90     }
91     return 0;
92 }
时间: 2024-10-08 11:48:49

蓝桥杯校内选拔赛/POJ 数独(深搜)的相关文章

[NOIP2009]靶形数独 深搜+枝杈优化

这道题,又是一位玄学搜索...... 我是用的蜗牛序搜的(顾名思义,@,这么搜),我正着搜80然后一反转比原来快了几十倍........一下AC....... 我的思路是这样的话我们可以从内到外或者从外到内搜索,这样的话我们就可以在一定程度上运用贪心,因为中间的价值大外面的价值小,我是作为一个从来没有玩过数独的人的思路...然而任何一个玩过数独的人都会先选可能状态少的优先搜索....... 对于这题里的数据,可行方案很少因此摆在我们面前的不是减去不优的解而是减去不成立的解,然而对于不成立的解在我

POJ 2488 深搜dfs、

题意:模拟国际象棋中马的走棋方式,其实和中国象棋的马走的方式其实是一样的,马可以从给定的方格棋盘中任意点开始,问是否能遍历全部格子,能的话输出字典序最小的走棋方式,否则输出impossible 思路:只要能遍历全部的格子,就一定会走A1这个点,而且这个点的字典序是最小的,保证了这点的话还需要保证dfs的8个方向也要按照字典序最小来走,这样就可以确保所走的路径就是字典序最小的 坑爹:自己忘记输出Scenario #i,一连WA了几发,就是不知道自己错在哪里,顺便发一个对照的程序吧我的程序过16MS

POJ 1321 深搜dfs

思路其实挺简单的,为什么我想不到呢!!! 原因分析:(1)题目还是做少了 (2)做题目的时候在放音乐 (3)最近脑袋都不愿意想思路总是想一些无用的 改进:(1)以后做题目坚决不开音乐,QQ直接挂隐身 (2)想题目的时候一定要认真,开启完全状态 (3)对自己再认真一点,加油 1 #include<cstdio> 2 #include<cstring> 3 const int qq=10; 4 char map[qq][qq]; 5 int vis[qq]; 6 int n,k,ans

(hdu)5547 Sudoku (4*4方格的 数独 深搜)

Problem Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny game himself. It looks like the modern Sudoku, but smaller. Actually, Yi Sima was playing it different. First of all, he tried to generate a 4×4 board wit

POJ 3009 深搜

 D - Curling 2.0 Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u SubmitStatusPracticePOJ 3009 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat differ

第五届蓝桥杯全国软件设计大赛--2013年校内选拔赛Java题目

第五届蓝桥杯全国软件设计大赛 2013年校内选拔赛Java题目 一.考生注意: (1)[结果填空题]要求参赛选手根据题目描述直接填写结果.求解方式不限.不要求源代码. 把答案存入[考生文件夹]下对应题号的文件中即可. (2)[代码填空题]要求参赛选手在弄清给定代码工作原理的基础上填写缺失的部分,使得程序逻辑正确.完整.所填写的代码不超过一条语句(即中间不能出现分号). 把填空的答案(仅填空处的答案,不包括题面已存在的代码)存入[考生文件夹]下对应题号的文件中中即可. (3)[编程题]要求选手设计

(暴力+深搜)POJ - 2718 Smallest Difference

原题链接: http://poj.org/problem?id=2718 题意: 给你几个数字,可以分成两个子集,然后分别按一定顺序排列组成一个数,求出这两只值差的绝对值的最小值. 分析: 反正也是刷着玩,果断先交一波全排列枚举的代码,果断TLE,然后开始想正解. 稍微想想,既然要差最小,肯定是两个数各一半.所以只要深搜出所有n/2(n为给定数字的个数)的组合,另外个n-n/2个数就有了. 但是枚举出来后的操作又想了很久,想过很多算法,都不怎么满意,最终用二分解决. 先把n/2和n-n/2全排列

POJ 2411 Mondriaan&#39;s Dream(状态压缩+深搜)

每一行的填充仅与上一行有关系,每行的目的都是至少填充满上一行. 当填充到i行的时候,i-1行某列没填充必须用竖直的方格填充,这是固定的,剩下其余的则搜索填充. 用2进制的01表示不放还是放 第i行只和i-1行有关 枚举i-1行的每个状态,推出由此状态能达到的i行状态 如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态. 然后用搜索扫一道在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,

poj 2837 Silver Matrix 不使用栈的深搜

题意: 给定k,让构造一个2^k*2^k的矩阵,使得对任意i,第i行和第i列由1,2,...2^k-1这2^k-1个数组成. 分析: 很明显是个深搜题.设n=2^k,则搜素树高度(状态空间维度)为n,每个状态可扩展n个状态,复杂度n^n,大概是512^512...所以必须有强力的剪枝而且不要用递归去写.一般对深搜来说,搜索树高度固定的话可以用for循环直接枚举,不固定话要用递归或栈,这题搜索树高度不固定(n为输入),怎么办呢?..这样可以清楚明了地搞定:dfs的while循环写法. 代码: //