DFS(考えられた簡単な例)
DFSはDepthFirst Searchの略です。つまり、私が行ける限り、最後まで1つの方法で歩き、最終的に行けなくなるまで、戻って別の方法を見つけます。
深度優先検索は、接続されたグラフをトラバースします
1)グラフの特定の頂点から開始して、xにアクセスし、mp [x]の値をtrueに設定します
。2)mp [w]の値がfalse、グラフ内のすべての頂点にアクセスするまで、wから再帰的にトラバースします。
/*
void dfs()
{
if(判断条件)
return ;
for(拓展状态)
{
判断合法
记录
dfs(继续搜);
回溯;
}
}
*/
一つ、迷路のタイプ
タイトル説明
Xiao Mingは現在ゲームをプレイしており、ゲームは教育レベルに達しています。迷路はNMのマトリックスです。
Xiao Mingの始点はマップ上で「S」で表され、終点は「E」で表され、障害物は「#」で表され、オープンスペースは「。」で表されます。
障害物は通過できません。Xiao Mingがポイント(x、y)にある場合、次のステップは4つの隣接するグリッド((x + 1、y)、(x-1、y)、(x、y)のいずれかにのみ進むことができます。 +1)、(x、y-1);
Xiao Mingは、彼が最初から最後まで歩くことができるかどうかを知りたがっています。
説明を入力してください:
本题包含多组数据。
每组数据先输入两个数字N,M
接下来N行,每行M个字符,表示地图的状态。
数据范围:
2<=N,M<=500
保证有一个起点S,同时保证有一个终点E.
出力の説明:
每组数据输出一行,如果小明能够从起点走到终点,那么输出Yes,否则输出No
例1
入る
3 3
S..
..E
...
3 3
S##
###
##E
出力
Yes
No
#include<bits/stdc++.h>
using namespace std;
int n,m;
char a[505][505],mp[505][505];
int aa[4][2]={1,0,-1,0,0,1,0,-1};
int xx,yy,x,y;
void dfs(int i,int j)
{
if(i==x&&j==y)
return ;//找到出口,从递归出来
mp[i][j]=1;//标记走过的地方
for(int k=0;k<=3;k++)
{
int dx=i+aa[k][0];
int dy=j+aa[k][1];
if(a[dx][dy]!='#'&&dx>0&&dx<=n&&dy>0&&dy<=m&&!mp[dx][dy])//判断是否能走
{
mp[dx][dy]=1;
dfs(dx,dy);//继续走到下一步
}
}
}
int main()
{
while(cin>>n>>m)
{
int i,j;
memset(mp,0,sizeof(mp));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='S')//记录起点
xx=i,yy=j;
if(a[i][j]=='E')
x=i,y=j;//记录终点
}
}
dfs(xx,yy);
if(mp[x][y])
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
第二に、数の選択、順列と組み合わせの問題、暴力の組み合わせ
タイトル説明
与えられたn個の整数x1、x2、...、xn x_nバツn個そして1つの整数k(k <n)。n個の整数から、オプションでk個の整数を加算して、それぞれ一連の合計を取得します。たとえば、n = 4、k = 3、および4つの整数が3、7、12、19の場合、すべての組み合わせとその合計は次のようになります。
3 + 7 + 12 = 22
3 + 7 + 19 = 29
7 + 12 + 19 = 38
3 + 12 + 19 = 34
ここで、何種類の合計が素数であるかを計算する必要があります。
たとえば、上記の例では、1種類の合計のみが素数です:3 + 7 + 19 = 29
入力フォーマット
キーボード入力、形式は次のとおりです。
n、k(1≤n≤20、k <n)
x1、x2、…、xn x_nバツn個(1≤xi≤5000000)
出力フォーマット
画面出力、形式は次のとおりです。1整数(条件を満たす種の数)。
サンプルの入力と出力
#1を入力してください
4 3
3 7 12 19
出力#1
1
#include<bits/stdc++.h>
using namespace std;
int a[10000],sum=0,ans=0;
int n,k;
int sushu(int f)
{
for(int i=2;i<=sqrt(f);i++)
{
if(f%i==0)
return 0;
}
return 1;
}
void dfs(int t,int x)//t表示还差多少个选到k个,x表示选到a【x】。
{
if(t==0)
ans+=sushu(sum);
else
{
x++;
for(int i=x;i<=n;i++)
{
sum+=a[i];
t--;
dfs(t,i);
sum-=a[i];//回溯
t++;
}
}
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
dfs(k,0);
cout<<ans<<endl;
getchar();
getchar();
return 0;
}
3、接続性
タイトル説明
長方形の配列は、0から9までの数字で構成されます。1から9までの数字はセルを表します。数字が同じであれば、セルの定義は同じセルです。指定された長方形の配列内のセルの数を見つけます。
入力フォーマット
最初の行の2つの整数は、マトリックスサイズnとmを表します。
次のn行、文字だけメートルの長さを有する各ライン0
に対して9
×nは文字列Mの行列。
出力フォーマット
行の整数はセルの数を表します。
サンプルの入力と出力
#1を入力してください
4 10
0234500067
1034560500
2045600671
0000000089
出力#1
4
指示/ヒント
データの規模と慣習
100%データの場合、1≤n、m≤100であることを確認してください。
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;
int a[105][105];
bool mp[105][105];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void dfs(int x,int y)//查找与该点连通的点
{
mp[x][y]=1;
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(a[nx][ny]==0 || mp[nx][ny]==1) continue;
dfs(nx,ny);
}
}
int main()
{
cin>>n>>m;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&a[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]==0 && a[i][j]!=0)//找到未走过的不为0的数
{
dfs(i,j);//将与这个数连通的全都标记为走过即为1
ans++;
}
}
}
cout<<ans;
return 0;
}