【十二月】第二次课堂练习
P1605
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; int barrier[10][10]; int walkx[5] = {0,0,0,1,-1}; //x方向可以走的选择 int walky[5] = {0,-1,1,0,0}; //y方向可以走的选择 int n,m,t,sx,sy,fx,fy; //n行,m列,t障碍数,sx,sy起点坐标,fx,fy终点坐标 int result = 0; int flag[10][10]; void dfs(int x, int y){ if(x == fx && y == fy){ result++; return; //返回 } else{ for(int i = 1; i <= 4; ++i){ //上下左右四个方向可以走 if(flag[x+walkx[i]][y+walky[i]] == 0 && barrier[x+walkx[i]][y+walky[i]] == 1){ //是否已走过 && 是否有障碍 flag[x][y] = 1; //原先的标记为已走过 dfs(x+walkx[i],y+walky[i]); flag[x][y] = 0; //回溯 } } } } int main(){ scanf("%d%d%d",&n,&m,&t); scanf("%d%d%d%d",&sx,&sy,&fx,&fy); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= m; ++j){ barrier[i][j] = 1; //初始化为地图都不为障碍,即都可以走 } } int barrierx,barriery; for(int i = 1; i<= t; ++i){ scanf("%d%d",&barrierx,&barriery); barrier[barrierx][barriery] = 0; //更新障碍处 } dfs(sx,sy); //从起点开始深搜 printf("%d\n",result); return 0; }
P1451
dfs:
#include<bits/stdc++.h> using namespace std; int g[105][105]; int n,m,sum=0; bool used[105][105];//标记数组 int dx[]={0,0,1,-1};//方向数组 int dy[]={1,-1,0,0}; //判断边界或是否被标记过 bool check(int a,int b) { if(a<1||a>n||b<1||b>m||g[a][b]==0||used[a][b]==false) return false; else return true; } //深搜 void dfs(int a,int b) { used[a][b]=false; for(int i=0;i<4;i++) { int tx,ty; tx=a+dx[i];ty=b+dy[i]; if(!check(tx,ty)) continue; dfs(tx,ty); used[tx][ty]=false; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%1d",&g[i][j]);//有两种输入方法,当用char定义g[i][j]时,用printf("%s",g[i]);;用int定义g[i][j]时,用scanf("%1d",&g[i][j]);来控制输入的个数 used[i][j]=true; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(g[i][j]!=0&&used[i][j]) { dfs(i,j); sum++; } } printf("%d",sum); return 0; }
bfs:
#include<bits/stdc++.h> using namespace std; int g[105][105]; struct node{ int x,y; }; int n,m,sum=0; bool used[105][105];//标记数组 int dx[]={0,0,1,-1};//方向数组 int dy[]={1,-1,0,0}; //判断边界或是否被标记过 bool check(int a,int b) { if(a<1||a>n||b<1||b>m||g[a][b]==0||used[a][b]==false) return false; else return true; } //广搜 void bfs(int a,int b) { queue<node> q; node now,next; used[a][b]=false; now.x=a;now.y=b; q.push(now);//入队 while(!q.empty()) { now=q.front();//返回队首元素 for(int i=0;i<4;i++) { int tx=now.x+dx[i]; int ty=now.y+dy[i]; if(!check(tx,ty)) continue; next.x=tx;next.y=ty; used[tx][ty]=false; q.push(next); } q.pop();//首元素出队 } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%1d",&g[i][j]); used[i][j]=true; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(g[i][j]!=0&&used[i][j]) { bfs(i,j); sum++; } } cout<<sum<<endl; return 0; }
P1784
#include<cstdio> using namespace std; const int N=10; const int group[9][9]= { 0,0,0,1,1,1,2,2,2, 0,0,0,1,1,1,2,2,2, 0,0,0,1,1,1,2,2,2, 3,3,3,4,4,4,5,5,5, 3,3,3,4,4,4,5,5,5, 3,3,3,4,4,4,5,5,5, 6,6,6,7,7,7,8,8,8, 6,6,6,7,7,7,8,8,8, 6,6,6,7,7,7,8,8,8 };//代表9个3*3的区域 bool row[N][N],col[N][N],gr[N][N]; //row[i][j]:判断第i行是否出现过数字j //col[i][j]:判断第i列是否出现过数字j //gr[i][j]:判断区域i是否出现过数字j int sudoku[N][N];//数独 bool check(int x,int y,int w) { if(row[x][w]||col[y][w]||gr[group[x][y]][w])//若该行 或 该列 或 该3*3区域出现过w return 0;//不能填充w return 1;//可填充 } void dfs(int x,int y) { if(x==9)//如果此时棋盘满足约束,则输出 { for(int i=0;i<9;i++) { for(int j=0;j<9;j++) printf("%d ",sudoku[i][j]); printf("\n"); } return; } int nxtx=x,nxty=y+1;//计算下一个状态 if(nxty==9) ++nxtx,nxty=0; if(sudoku[x][y]!=0)//原来就有数字,直接跳过 dfs(nxtx,nxty); else//原来没有数字,枚举所有可能:填充1-9 { for(int j=1;j<=9;j++) if(check(x,y,j)) { row[x][j]=col[y][j]=gr[group[x][y]][j]=1; sudoku[x][y]=j; dfs(nxtx,nxty);//搜索下一状态 sudoku[x][y]=0;//回溯,复原棋盘 row[x][j]=col[y][j]=gr[group[x][y]][j]=0; } } } int main() { for(int i=0;i<9;i++) for(int j=0;j<9;j++) { int a; scanf("%d",&a); if(a==0) continue; row[i][a]=1;//第i行已有a col[j][a]=1;//第j列已有a gr[group[i][j]][a]=1;//i行j列所在区域 已有a sudoku[i][j]=a;//填充入sudoku } dfs(0,0); return 0; }
P1219
#include <stdio.h> #include <string.h> #include <stdlib.h> int n; int a[100]; int visited[3][100]; int count=0; void dfs(int step){ int i,j,flag; if(step==n+1){ count++; if(count<=3){ for(i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); } return; } for(i=1;i<=n;i++){ if(!visited[0][i]&&!visited[1][i+step]&&!visited[2][step-i+n]){ visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=1; a[step]=i; dfs(step+1); visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=0; } } } int main(){ memset(visited,0,sizeof(visited)); scanf("%d",&n); dfs(1); printf("%d\n",count); return 0; }