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 }
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 }