POJ 2676 数独(DFS)

Sudoku

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 21612   Accepted: 10274   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

题意:把一个9行9列的网格,再细分为9个3*3的子网格,要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字,即每行、每列、每个子网格内都不允许出现相同的数字,填完数独。

分析:直接搜索,标记行、列、块,值得一提的是倒着搜比正着搜效率高出许多,这也算是一个技巧。

代码:

  1 ////#include "bits/stdc++.h"
  2 #include "cstdio"
  3 #include "map"
  4 #include "set"
  5 #include "cmath"
  6 #include "queue"
  7 #include "vector"
  8 #include "string"
  9 #include "cstring"
 10 #include "time.h"
 11 #include "iostream"
 12 #include "stdlib.h"
 13 #include "algorithm"
 14 #define db double
 15 #define ll long long
 16 #define vec vector<ll>
 17 #define Mt  vector<vec>
 18 #define ci(x) scanf("%d",&x)
 19 #define cd(x) scanf("%lf",&x)
 20 #define cl(x) scanf("%lld",&x)
 21 #define pi(x) printf("%d\n",x)
 22 #define pd(x) printf("%f\n",x)
 23 #define pl(x) printf("%lld\n",x)
 24 #define rep(i, x, y) for(int i=x;i<=y;i++)
 25 const int N   = 1e6 + 5;
 26 const int mod = 1e9 + 7;
 27 const int MOD = mod - 1;
 28 const db  eps = 1e-18;
 29 const db  PI  = acos(-1.0);
 30 using namespace std;
 31 int t;
 32
 33 int R()
 34 {
 35     int x=0,f=1;char ch=getchar();
 36     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 37     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 38     return x*f;
 39 }
 40 char s[10][10];
 41 int  a[10][10];
 42 bool ok(int ans,int x,int y)
 43 {
 44     for(int i=0;i<9;i++)
 45         if(a[i][y]==ans) return 0;
 46     for(int i=0;i<9;i++)
 47         if(a[x][i]==ans) return 0;
 48     int xx=x-x%3,yy=y-y%3;
 49     for(int i=xx;i<xx+3;i++)
 50         for(int j=yy;j<yy+3;j++)
 51             if(a[i][j]==ans) return 0;
 52     return 1;
 53 }
 54 bool okk=0;
 55 void dfs(int x,int y,int cnt)
 56 {
 57     if(cnt==81){
 58         okk=1;//满足条件后立刻结束,并标记
 59         return;
 60     }
 61     while(a[x][y]){
 62         if(y==8) x++,y=0;
 63         else y++;
 64         if(x==9) {okk=1;return;}//满足条件后立刻结束,并标记
 65     }
 66     for(int i=1;i<=9;i++){
 67         if(ok(i,x,y)){
 68             a[x][y]=i;
 69             if(y==8) dfs(x+1,0,cnt+1);
 70             else     dfs(x,y+1,cnt+1);
 71             if(okk) return;//满足条件后立刻结束
 72             a[x][y]=0;
 73         }
 74     }
 75     return;
 76 }
 77 int main()
 78 {
 79     t=R();
 80     while(t--)
 81     {
 82         int cnt=81;
 83         memset(a,0, sizeof(a));
 84         memset(s,0, sizeof(s));
 85         okk=0;
 86         for(int i=0;i<9;i++)
 87         {
 88             scanf("%s",s[i]);
 89             for(int j=0;j<9;j++){
 90                 a[i][j]=s[i][j]-‘0‘;
 91                 if(!a[i][j]) cnt--;
 92             }
 93         }
 94         dfs(0,0,cnt);//输出即为满足条件的,结束后的情况。
 95         for(int i=0;i<9;i++){
 96             for(int j=0;j<9;j++){
 97                 printf("%d",a[i][j]);
 98             }
 99             puts("");
100         }
101     }
102 }
时间: 2024-11-08 21:45:41

POJ 2676 数独(DFS)的相关文章

ACM : POJ 2676 SudoKu DFS - 数独

SudoKu Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu POJ 2676 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 c

POJ 3074&amp;&amp;2676 数独DFS

经典数独问题 用DFS模拟数独解法,找摒除解和余数解 数独解法:http://www.sudokufans.org.cn/forums/topic/8/ 2676 #include "stdio.h" #include "string.h" struct node { int x,y; int s[10]; // 对于每个空格,数字i是否可用 int sum; // 对于每个空格,一共可以填入的数字种数 }order[101]; int cnt; // 总空格数 c

Poj 2676 Sudoku[dfs]

题目大意: 九宫格问题,也有人叫数独问题 把一个9行9列的网格,再细分为9个3*3的子网格,要求每行.每列.每个子网格内都只能使用一次1~9中的一个数字,即每行.每列.每个子网格内都不允许出现相同的数字. 0是待填位置,其他均为已填入的数字. 要求填完九宫格并输出(如果有多种结果,则只需输出其中一种) 如果给定的九宫格无法按要求填出来,则输出原来所输入的未填的九宫格 思路: DFS 深搜 char map[10][10];/*数据存储*/bool row[10][10];/*行存在数*/bool

POJ 2676 数独

题意: 给你一个9*9的未完成的数独,将其填完 思路: 暴搜 从第一个位置搜起,有数字就直接跳过搜下一个位置,没数字就填数字 .通过行,列,九宫格不能重复填数,把能填的数填进去就可以了 //By DXY 2018.04.27 #include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm>

poj 2676 数独 Dancing-Links(DLX)

题目大意:....数独还用我说么 首先一般的解法都是爆搜,爆搜的话绝对懒得做..于是我作死去学了Dancing-Links数据结构优化的X算法,简称DLX算法 Dancing-Links虽然名字好听,但是其实实质就是双向十字链表..但是由于调试的时候各种挂,指针还看着及其闹心(经常调试链式结构的人一定深有同感),所以只能在调试区各种加指针删指针,来回飞舞的指针,即Dancing-Links... 这算法的作者太有才了,不得不说.... DLX算法主要解决的是精确覆盖问题,具体做法见 http:/

poj 2676 Sudoku (dfs)

链接:poj 2676 题意:给定一个未完成的数独,0是待填位置,其他均为已填入的数字.如果能将其 补充完整,则输出补充完整的数独(有多组答案输出任意一组),否则原样输出 数独:一个9行9列的网格,包括9个3*3的子网格,要求每行.每列.每个子网格内 都只能使用一次1-9中的一个数字, 即每行.每列.每个子网格内都不允许出现相同的数字. 分析:对于每一个未填的格,依次判断它所在行.列.子网格是否填了1-9, 若都未填,先填上该值,继续搜索, 若无法填写了,再回溯,填上其他可能的值,继续搜索 看别

POJ 2676 Sudoku (数独)

经典搜索问题,主要是时间上的优化,我用了三个辅助数组记录信息 row[i][k] = 1表示第i行数字k已经被使用,col[j][k] = 1表第j列数字k已经被使用,blo[i][k]表示第i个小九宫格中数字k已经被使用 还有很重要的一个优化(没有优化的话可能会超时,或者非常慢,像POJ讨论区里有很多说正着搜超时,倒着搜0ms,这的确是一个可以用的方法,但是有一定的随机性),每次填数字时,先扫描一遍整个矩阵,找出可选数字情况最少的那个0所在的地方,优先填这里,这样会使得搜索树尽可能的"瘦&qu

POJ 2676 Sudoku (搜索,Dancing Links)

题目: http://poj.org/problem?id=2676 题意: 数独,每行1-9,每列1-9,每3*3小格1-9,填数,不能重复 方法:Dancing Links(16ms)或者DFS暴搜(400-900ms) Dancing Links(DLX) 是为了解决矩阵精确覆盖问题的算法,算法效率非常高 使用DLX解决的问题必须转化为矩阵精确覆盖问题: 1.DLX详解: http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html 2

POJ 2676 Sudoku

题目链接:http://poj.org/problem?id=2676 数独问题.用dancing links解决. 建图参考 http://wenku.baidu.com/link?url=3Tk5gVYew3mSQ2f2LxDODxPg3v-yqJPUaEkuZpfkHTxfSPQuM_n8TGl2Swp68XQY9MYN2BENZ-pmv9dpoh3Ulqt1lT-ZNo90jcJyi1eXasm 要注意的就是搜索的时候 要先搜索 那一列中节点最少的,否则时间会很长. 1 #include