DFS & BFS

 

1.数独 DFS

 

问题:用数字1-9填充该9×9的数据块,条件:空位置填数,该行、该列、该所在的3×3(黑线划分)小块,不得有重复出现的数字

思路:DFS

用三个二维数组分别存储:值为 1则说明出现过

  r[i][x]  第 i 行 x 值 是否出现过

  c[j][x] 第 j 列 x 值 是否出现过 

  b[k][x] 第 k 快(该9×9 的数独区由9块3×3的小区域组成) x 值是否出现过 :(i/3*3+j/3 这个很重要,用来判断该位置属于那个块)

定义一个结构体数组存放空点位置,每次DFS递归空点位置的下标,如果下标打过了空点的总数量,则递归结束。

写完记得 memset 三个数组。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 struct P
 5 {
 6     int x,y;
 7 } p[81];
 8 char s[9][9];
 9 int r[10][10],c[10][10],b[10][10];
10 int ok,cut;
11 void init()
12 {
13     int k=0;
14     for(int i=0; i<9; i++)
15         for(int j=0; j<9; j++)
16             if(s[i][j]!='0')
17                 r[i][s[i][j]-'0']=c[j][s[i][j]-'0']=b[i/3*3+j/3][s[i][j]-'0']=1;
18             else
19                 p[cut].x=i,p[cut].y=j,cut++;
20 }
21 int check(int x,int y,int v)
22 {
23     if(r[x][v]||c[y][v]||b[x/3*3+y/3][v])return 0;
24     return 1;
25 }
26 void print()
27 {
28     for(int i=0; i<9; i++)
29     {
30         for(int j=0; j<9; j++)
31             printf("%c",s[i][j]);
32         printf("\n");
33     }
34 }
35 void dfs(int step)
36 {
37     if(step==cut)
38     {
39         ok=1;
40         print();
41         return ;
42     }
43     int xx,yy;
44     for(int i=1; i<10; i++)
45     {
46         if(check(p[step].x,p[step].y,i))
47         {
48             xx=p[step].x,yy=p[step].y;
49             r[xx][i]=c[yy][i]=b[xx/3*3+yy/3][i]=1;
50             s[xx][yy]=i+'0';
51             dfs(step+1);
52             if(ok)return;
53             r[xx][i]=c[yy][i]=b[xx/3*3+yy/3][i]=0;
54             s[xx][yy]='0';
55         }
56     }
57 }
58 int main()
59 {
60     int T;
61     scanf("%d",&T);
62     while(T--)
63     {
64         memset(c,0,sizeof(c));
65         memset(r,0,sizeof(r));
66         memset(b,0,sizeof(b));
67         cut=ok=0;
68         for(int i=0; i<9; i++)
69             scanf("%s",s[i]);
70         init();
71         dfs(0);
72     }
73     return 0;
74 }
View Code

 

2。POJ 3984 迷宫问题 BFS

问题:给出一个 5×5 二位数组,由1、0两个数填充,1为墙0为路,输出从(0,0)到(4,4)最短路径。

思路:BFS  用一个结构体标识一个点,该点具有x,y位置信息与距离(0,0)的距离和指向前一个点的信息。

用一个与输入原数据相同的数组 r 记录是否访问过该位置。

利用队列对合适的点进行遍历,若该点位置为最终位置,进行输出即可。

 1 #include<cstdio>
 2 #include<queue>
 3 #include<iostream>
 4 using namespace std;
 5 int s[5][5],r[5][5];
 6 int dx[4]= {1,0,-1,0},dy[4]= {0,1,0,-1};
 7 struct Point
 8 {
 9     int x,y,d;
10     Point *f;
11     Point() {}
12     Point(int x1,int y1,int d1)
13     {
14         x=x1;
15         y=y1;
16         d=d1;
17         f=NULL;
18     }
19 };
20 void print(Point* p)
21 {
22     int t[25][2];
23     int k=0;
24     while(p!=NULL)
25     {
26         t[k][0]=p->x;
27         t[k][1]=p->y;
28         k+=1;
29         p=p->f;
30     }
31     for(int i=k-1; i>=0; i--)
32         cout<<'('<<t[i][0]<<", "<<t[i][1]<<')'<<endl;
33 }
34 void bfs(int x,int y,int d)
35 {
36     queue<Point> Q;
37     Q.push(Point(x,y,d));
38     r[x][y]=1;
39     while(!Q.empty())
40     {
41         Point* p=new Point();
42         p=&Q.front();
43         Q.pop();
44         if(p->x==4&&p->y==4)
45         {
46             print(p);
47             break;
48         }
49         for(int i=0; i<4; i++)
50         {
51             int nx=p->x+dx[i],ny=p->y+dy[i];
52             if(nx>=0&&nx<5&&ny>=0&&ny<5&&r[nx][ny]==0&&s[nx][ny]==0)
53             {
54                 r[nx][ny]=1;
55                 Point t;
56                 t.x=nx,t.y=ny,t.d=p->d+1;
57                 t.f=p;
58                 Q.push(t);
59             }
60         }
61 
62     }
63 }
64 int main()
65 {
66     for(int i=0; i<5; i++)
67         for(int j=0; j<5; j++)
68             scanf("%d",&s[i][j]);
69     bfs(0,0,0);
70     return 0;
71 }
View Code

 

posted @ 2017-04-06 21:15  马丁黄瓜啊  阅读(211)  评论(0编辑  收藏  举报