7.深度优先搜索 DFS
1.迷宫问题
#include<iostream>
#include<string>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
bool in(int x,int y){
return 0<=x && x<n && 0<=y && y<m;
}
bool dfs(int x,int y){
if(maze[x][y]=='T'){
return true;
}
vis[x][y]=1;
maze[x][y]='m';
int tx=x-1,ty=y;
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
tx=x,ty=y-1;
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
tx=x+1,ty=y;
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
tx=x,ty=y+1;
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
vis[x][y]=0;
maze[x][y]='.';
return false;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>maze[i];
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i,y=j;
}
}
}
if(dfs(x,y)){
for(int i=0;i<n;i++){
cout<<maze[i]<<endl;
}
} else {
cout<<"No!"<<endl;
}
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool in(int x,int y){
return 0<=x && x<n && 0<=y && y<m;
}
bool dfs(int x,int y){
if(maze[x][y]=='T'){
return true;
}
vis[x][y]=1;
maze[x][y]='+';
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
}
vis[x][y]=0;
maze[x][y]='.';
return false;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>maze[i];
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i,y=j;
}
}
}
if(dfs(x,y)){
for(int i=0;i<n;i++){
cout<<maze[i]<<endl;
}
} else {
cout<<"No!"<<endl;
}
return 0;
}
#include<iostream>
using namespace std;
int n,m;
char maze[105][105];
bool via[105][105];
void dfs(int x,int y) {
if(maze[x][y]=='T') {
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cout<<maze[i][j];
}
cout<<endl;
}
return ;
}
if(x<0 || x>=n || y<0 || y>=m) {
return ;
}
if(!via[x][y] && maze[x][y]!='*') {
via[x][y]=true;
maze[x][y]='m';
dfs(x+1,y);
dfs(x-1,y);
dfs(x,y-1);
dfs(x,y+1);
via[x][y]=false;
maze[x][y]='.';
}
}
int main() {
cin>>n>>m;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cin>>maze[i][j];
}
}
int x,y;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(maze[i][j]=='S') {
x=i;
y=j;
}
}
}
dfs(x,y);
return 0;
}
2.象棋走马
#include<iostream>
using namespace std;
char s[10][10];
int dir[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
bool f;
bool vis[10][10];
int ans=1000000;
bool in(int x,int y){
return 0<=x && x<10 && 0<=y && y<9;
}
void dfs(int x,int y,int step){
vis[x][y]=true;
if(s[x][y]=='T'){
f=true;
if(step<ans){
ans=step;
}
return;
}
for(int i=0;i<8;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&s[tx][ty]!='#'&&!vis[tx][ty]){
dfs(tx,ty,step+1);
}
}
}
int main(){
int x,y;
for(int i=0;i<10;i++){
for(int j=0;j<9;j++){
cin>>s[i][j];
}
}
for(int i=0;i<10;i++){
for(int j=0;j<9;j++){
if(s[i][j]=='S'){
x=i;
y=j;
break;
}
}
}
dfs(x,y,0);
if(f){
cout<<"Yes "<<ans<<endl;
}else{
cout<<"No"<<endl;
}
return 0;
}
3.草地块问题
#include<iostream>
using namespace std;
char mp[105][105];
bool vis[105][105];
int n,m;
void dfs(int x,int y){
if(x<0 || x>=n || y<0 || y>=m || vis[x][y] || mp[x][y]=='.' ){
return ;
}
vis[x][y]=true;
dfs(x-1,y);
dfs(x+1,y);
dfs(x,y-1);
dfs(x,y+1);
}
int main(){
cin>>n>>m;
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>mp[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(!vis[i][j] && mp[i][j]=='#'){
cnt++;
dfs(i,j);
cout<<i<<j<<endl;
}
}
}
cout<<cnt<<endl;
return 0;
}
4.树的子节点
题目:现要调查族谱系中每个人的直属后代(含直属后代的直属后代)一共有多少人
输入:族谱中的人数n;接下来n-1行,每行第一个数字x代表父代,第二个数字y代表子代
输出:n行,每行代表第几个人的直属后代数
示例输入:
4
1 2
1 3
2 4
示例输出:
3
1
0
0
解题思路:
与树的子代结构类似,可用递归计算
#include<iostream>
#include<vector>
using namespace std;
vector<int> son[100005];
bool f[100005];
int ans[100005];
int dfs(int u) {
int ret=0;
for(int i=0; i<son[u].size(); i++) {
ret+=dfs(son[u][i]);
}
ans[u]=ret;
return ret+1;
}
int main() {
int x,y,n,u;
cin>>n;
for(int i=0; i<n-1; i++) {
cin>>x>>y;
son[x].push_back(y);
f[y]=true;
}
for(int i=1; i<=n; i++) {
if(!f[i]) {
u=i;
break;
}
}
dfs(u);
for(int i=1; i<=n; i++) {
cout<<ans[i]<<endl;
}
return 0;
}
5.马可以走到哪
#include<iostream>
using namespace std;
int n,m;
char mp[105][105];
bool vis[105][105];
int a[8][2]= {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};
void dfs(int x,int y,int step) {
if(x<0 || x>=n || y<0 || y>=m ) {
return ;
}
if(step >3) {
return ;
}
mp[x][y]='#';
for(int i=0; i<8; i++) {
dfs(x+a[i][0],y+a[i][1],step+1);
}
}
int main() {
cin>>n>>m;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
mp[i][j]='.';
}
}
int x,y;
cin>>x>>y;
mp[x][y]='B';
dfs(x-1,y-1,0);
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cout<<mp[i][j];
}
cout<<endl;
}
return 0;
}