[DFS]poj2676(2918)

题意:

数独问题,给出一些点,然后要求填满格子。每行没列1-9不能重复,每个3*3的小格子也不能重复。

分析:

暴力搜索,那么主要的问题就是每次如何判断是否冲突。行和列的比较好想,row[i][j]=1表示第i行的j已经被占了,col[i][j]=1表示第i列的j已经被占了,那么每个小格子呢?

首先,每行每列都是012、345、678那么每个j/3表示它在这以行的第j/3个格子里,i/3表示在第i/3行的格子,那么i/3*3+j/3就表示该点处于那个小格子里,同理g[i][j]表示第i个格子里的j已经被占了。

ok,剩下的就是代码递归实现了。

另外poj2918和本题是一样的,只不过输入输出格式不一样。亲测代码改过能AC。另外,poj的数独问题还有poj3074,poj3076 ,难度分别是poj2076=poj2918

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 1000
using namespace std;
char mp[10][10];
int grid[10][10];
bool row[10][10],col[10][10];
bool g[10][10];

bool dfs(int d)
{
   // cout<<d<<endl;
   if(d==81)return true;
   int x=d/9+1,y=d%9+1;
   bool f=false;
   if(grid[x][y])
   return dfs(d+1);
   else
   {
       int t=((x-1)/3)*3+(y-1)/3+1;
        for(int i=1;i<=9;i++)
        {
             //cout<<"EEE"<<f<<endl;
            if( !col[y][i] && !row[x][i] && !g[t][i])
            {
                grid[x][y]=i;
                col[y][i]=true;row[x][i]=true;g[t][i]=true;
                f= dfs(d+1);

                if(f)return true;
                else{
                col[y][i]=false;row[x][i]=false;g[t][i]=false;grid[x][y]=0;
                }
            }
       }
   }
   return false;
}
int main()
{
  //  read;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j;
        memset(row,false,sizeof(row));
        memset(col,false,sizeof(col));
        memset(grid,0,sizeof(grid));
        memset(g,false,sizeof(g));

        for(i=1;i<=9;i++)
        {
            for(j=1;j<=9;j++)
            {
                cin>>mp[i][j];
                grid[i][j]=mp[i][j]-‘0‘;
                if(grid[i][j])
                {
                    int tmp=grid[i][j];
                    row[i][tmp]=true;
                    col[j][tmp]=true;
                    int x=((i-1)/3)*3+(j-1)/3+1;
                    g[x][tmp]=true;
                }
            }

        }
       bool flag= dfs(0);
      // cout<<flag<<endl;
        for(i=1;i<=9;i++)
        {
            for(j=1;j<=9;j++)cout<<grid[i][j];
            cout<<endl;
        }
    }
}
时间: 2024-08-10 21:30:30

[DFS]poj2676(2918)的相关文章

POJ2676 2918 Sudoku 暴搜

#include <cstdio> #include <iostream> #include <iostream> #include <algorithm> using namespace std; int s[][2] = {{1,1},{1,4},{1,7},{4,1},{4,4},{4,7},{7,1},{7,4},{7,7}}; int a[10][10]; int ch[] = {0,0,0,1,1,1,2,2,2, 0,0,0,1,1,1,2,2

poj 2918 Tudoku 数独dfs

题意: 解数独游戏. 分析: 这道数独的数独直接dfs就能过. 代码: //poj 2918 //sep9 #include<iostream> using namespace std; char s[12][12]; int board[12][12]; int CheckSquare[12][12]; int CheckRow[12][12]; int CheckColumn[12][12]; int ok; int GetSquareId(int i,int j) { int r=i/3

poj2676 Sudoku(DFS)

做了很久还是参考了别人的答案orz,其实也不难啊.我要开始学一下怎么写搜索了... 题目链接:poj2676 Sudoku 题解:暴力搜索,DFS每个空白格子所放数字. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 bool row_f[9][

POJ2676 Sudoku - DFS

POJ2676 Sudoku 传送门 题意: 填充未完成的数独...(就这么简单.... 思路: 爆搜即可. 可行性剪枝:用三个\(bool\)数组分别记录行.列.\(3*3\)的块中,\(9\)种数字的使用情况 AC Code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=9+10; char s[N][N];int mp[N][N];

POJ 2676/2918 数独(dfs)

思路:记录每行每列每一个宫已经出现的数字就可以.数据比較弱 另外POJ 3074 3076 必须用剪枝策略.但实现较麻烦,还是以后学了DLX再来做吧 //Accepted 160K 0MS #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N =15; char sudo[N][N]; bool vi

poj2676——dfs

POJ 2676  dfs Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14640   Accepted: 7217   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 o

POJ--2676&amp;HDU--1421(数独,dfs)

Sudoku Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status 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

POJ 2918 Tudoku [搜索]

和POJ2676一样哈,,, 原谅我水题目数 = =!... #include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> using namespace std; int map[10][10]; char tmp[10][10]; bool row[10][10]; bool col[10][10]; bool grid[10][10]; bool DFS(int

POJ2676 Sudoku [数独]

好题,也很实用,犯了几个错误 1.在枚举赋值的时候,思维有个错误:当当前的赋值不能填完这个数独,应该是继续下一个循环,而不是return false 终止枚举 2.Generic Programing写错了,,,本来那个memset想写成Generic Programing的,,,然后,永远只有第一组结果对 不说了,泪哈,,, #include <cstdio> #include <cstring> #include <iostream> #include <cs