POJ 2676 挺复杂的一道深搜

这道题之前就做了,一直没写题解,很不错的一道深搜题。这道题没什么剪枝优化,思路就是将空白格子的位置放入一个数组,然后用dfs尝试每个空白格子所放的数字。

Sudoku

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

 1 #include<iostream>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6 short row[9][10],col[9][10],block[9][10];//rowFlag[i][num]=1表示在第i行已经放了数字num,后2个分别表示列、块
 7 int board[9][10];
 8 struct pos
 9 {
10     int x,y;
11 }blank[81];
12 int Getnum(int x,int y)//状态压缩
13 {
14     int xx=x/3;
15     int yy=y/3;
16     return xx*3+yy;
17 }
18 void setallflag(int x,int y,int num,int f)
19 {
20     row[x][num]=f;
21     col[y][num]=f;
22     block[Getnum(x,y)][num]=f;
23 }
24 bool isok(int x,int y,int num)
25 {
26     return !row[x][num]&&!col[y][num]&&!block[Getnum(x,y)][num];
27 }
28 bool dfs(int n)
29 {
30     if(n<0) return true;
31     int x=blank[n].x;
32     int y=blank[n].y;
33     for(int num=1;num<=9;num++)
34     {
35         if(isok(x,y,num))
36         {
37             board[x][y]=num;
38             setallflag(x,y,num,1);
39             if(dfs(n-1))
40                 return true;
41             setallflag(x,y,num,0);
42         }
43     }
44     return false;
45 }
46 int main()
47 {
48     int t;
49     cin>>t;
50     while(t--)
51     {
52         memset(row,0,sizeof(row));
53         memset(col,0,sizeof(col));
54         memset(block,0,sizeof(block));
55         memset(blank,0,sizeof(blank));
56         int flag=0;
57         for(int i=0;i<9;i++)
58             for(int j=0;j<9;j++)
59         {
60             char c;
61             cin>>c;
62             board[i][j]=c-‘0‘;
63             if(board[i][j])
64                 setallflag(i,j,board[i][j],1);
65             else
66             {
67                 blank[flag].x=i;
68                 blank[flag].y=j;
69                 flag++;
70             }
71         }
72         if(dfs(flag-1))
73         {
74             for(int i=0;i<9;i++)
75             {
76                 for(int j=0;j<9;j++)
77                     cout<<board[i][j];
78                 cout<<endl;
79             }
80         }
81     }
82     return 0;
83 }

时间: 2024-10-07 22:53:13

POJ 2676 挺复杂的一道深搜的相关文章

POJ 1129-Channel Allocation(四色定理+迭代深搜)

题目链接:传送门 题意:n个信号站,给出连接情况,要用信号覆盖所有信号站,要求相连的信号站不能用同一个信号. 等价问题==无向图染色==四色定理(每个平面地图都可以只用四种颜色来染色,而且没有两个邻接的区域颜色相同.已证明) 思路:深搜一条路(枚举颜色,判断当前点用已有的颜色能不能染,如不能则加一种颜色,判断强判就行了),搜到头答案就出来了..然后返回就可以了 注意单复数.. #include <algorithm> #include <iostream> #include <

poj 1164 The Castle (入门深搜)

题目: 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | # # # # # #---#####---#####---#####---# 3 # | | # # # # # #---#########---#####---#---# 4 # # | | | | # # ############################# (Figure 1)

poj 3134 Power Calculus iddfs(迭代深搜)

iddfs入门题. //poj 3134 //sep9 #include <iostream> using namespace std; int n,deep; int a[30]; bool iddfs(int pos) { int t; if(pos>deep) return false; if(a[pos]<<(deep-pos)<n) return false; if(a[pos]==n) return true; for(int i=1;i<=pos;+

POJ 1979 Red and Black (深搜)

Red and Black Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 23095   Accepted: 12467 Description There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a

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 - 2718 Smallest Difference

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

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循环写法. 代码: //

poj 3009 Curling 2.0 深搜

http://poj.org/problem?id=3009 题意:一个小球在一个格子里滑行,当你给它一个力时,他会一直滑,直到前方碰到一个雪球停止,这时前方的雪球会消失,你继续给该小球任意一个方向的力...问至少需要几步才能到达到终点. 分析: 一般在求  最短路    时会用到   广搜,但是  本题  在搜索时, 每走一步, 现场状态是需要改变的 ,如果该步不满足,又需要把现场状态还原回去  ,这样   深搜  才能满足 因此用  深搜     只能把   所有能到达终点的路的步数    

简单深搜(poj 3009)

题目链接:http://poj.org/problem?id=3009 题目:冰壶撞向目的地,只有遇到"1"才能停下来,并且把"1"撞成"0".只能横冲直撞,不允许蛇皮走位等等骚操作.从"2"要撞到"3",周围有"0",才能向有"0"的地方滑.运动员只能推十次,问最少要多少次才到"3"? 用深搜遍历每一个方向. 1 #include<stdi