本文整理了 ED_Builder 在初学搜索算法时做的题目
DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <bits/stdc++.h> using namespace std;int n,a[20 ],ans;bool vis_lie[30 ],vis_l[30 ],vis_r[30 ];void print () { if (ans>3 ) return ; for (int i=1 ;i<=n;i++) cout<<a[i]<<' ' ; cout<<endl; return ; } void dfs (int x) { if (x>n) { ans++; print (); return ; } for (int i=1 ;i<=n;i++) { if (!vis_lie[i]&&!vis_l[x-i+n]&&!vis_r[x+i]) { vis_lie[i]=true ,vis_l[x-i+n]=true ,vis_r[x+i]=true ; a[x]=i; dfs (x+1 ); vis_lie[i]=false ,vis_l[x-i+n]=false ,vis_r[x+i]=false ; } } } int main () { cin>>n; dfs (1 ); cout<<ans; return 0 ; }
P1 - DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <bits/stdc++.h> using namespace std;int n,a[20 ];bool vis[20 ];void print () { for (int i=1 ;i<=n;i++) cout<<setw (5 )<<a[i]; cout<<endl; return ; } void dfs (int x) { if (x>n) { print (); return ; } for (int i=1 ;i<=n;i++) { if (!vis[i]) { a[x]=i; vis[i]=true ; dfs (x+1 ); vis[i]=false ; } } } int main () { cin>>n; dfs (1 ); return 0 ; }
P2 - 枚举优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <bits/stdc++.h> using namespace std;int main () { int n; cin>>n; int num[n]; for (int i=1 ;i<=n;i++) num[i]=i; do { for (int i=1 ;i<=n;i++) cout<<setw (5 )<<num[i]; cout<<endl; }while (next_permutation (num+1 ,num+1 +n)); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream> #include <cstring> using namespace std;int n,m,t,sx,sy,fx,fy,ans;int dx[5 ]={1 ,0 ,-1 ,0 },dy[5 ]={0 ,-1 ,0 ,1 };bool map[10 ][10 ];void dfs (int x,int y) { if (x==fx&&y==fy) { ans++; return ; } for (int i=0 ;i<4 ;i++) { int tmp_x=dx[i]+x,tmp_y=dy[i]+y; if (tmp_x>=1 &&tmp_x<=n&&tmp_y>=1 &&tmp_y<=m&&map[tmp_x][tmp_y]) { map[tmp_x][tmp_y]=false ; dfs (tmp_x,tmp_y); map[tmp_x][tmp_y]=true ; } } } int main () { memset (map,true ,sizeof (map)); cin>>n>>m>>t>>sx>>sy>>fx>>fy; for (int i=1 ;i<=t;i++) { int x,y; cin>>x>>y; map[x][y]=false ; } map[sx][sy]=false ; dfs (sx,sy); cout<<ans; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h> using namespace std;int n,k,x[25 ],ans;bool vis[25 ];bool check_prime (int n) { if (n<=1 ) return false ; for (int i=2 ;i<=sqrt (n);i++) if (n%i==0 ) return false ; return true ; } void dfs (int pos,int cnt,int sum) { if (cnt>=k) { if (check_prime (sum)) ans++; return ; } for (int i=pos;i<=n;i++) { if (vis[i]) { vis[i]=false ; dfs (i+1 ,cnt+1 ,sum+x[i]); vis[i]=true ; } } } int main () { memset (vis,true ,sizeof (vis)); cin>>n>>k; for (int i=1 ;i<=n;i++) cin>>x[i]; dfs (1 ,0 ,0 ); cout<<ans; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <bits/stdc++.h> #define int long long using namespace std;int m,n;int mp[20 ][20 ],vis[20 ][20 ],have_solution=false ;int begin_x,begin_y,end_x,end_y;int dx[5 ]={0 ,-1 ,0 ,1 },dy[5 ]={-1 ,0 ,1 ,0 };int ans[100000 ][3 ],k;void print () { if (have_solution==false ) have_solution=true ; for (int i=0 ;i<k;i++) cout<<'(' <<ans[i][1 ]<<',' <<ans[i][2 ]<<')' <<"->" ; cout<<'(' <<end_x<<',' <<end_y<<')' <<endl; } void dfs (int x,int y) { if (x==end_x&&y==end_y) { print (); return ; } for (int i=0 ;i<4 ;i++) { int nxt_x=x+dx[i],nxt_y=y+dy[i]; if (mp[nxt_x][nxt_y]==1 &&vis[nxt_x][nxt_y]==0 ) { vis[x][y]=1 ; ans[k][1 ]=x,ans[k][2 ]=y; k++; dfs (nxt_x,nxt_y); vis[x][y]=0 ; k--; } } } signed main () { cin>>m>>n; for (int i=1 ;i<=m;i++) for (int j=1 ;j<=n;j++) cin>>mp[i][j]; cin>>begin_x>>begin_y>>end_x>>end_y; dfs (begin_x,begin_y); if (!have_solution) cout<<-1 ; return 0 ; }
BFS
注意: BFS 不能用于加权图 ,因为 BFS 只会查找边数最少 的路径
例如 100 -> 100 和 1 -> 1 -> 1 -> 1
BFS 会选择 100 -> 100
当数据范围较小( ≤ 20 \le20 ≤ 2 0 )时,用 DFS 也不是不可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <iostream> #include <queue> using namespace std;struct Point { int x,y; }; int n;char map[1005 ][1005 ];int dis[1005 ][1005 ];int dx[]={1 ,0 ,-1 ,0 };int dy[]={0 ,1 ,0 ,-1 };int start_x,start_y,final_x,final_y;queue<Point> q; void bfs (int x,int y) { q.push ((Point){x,y}); dis[x][y]=0 ; while (!q.empty ()) { Point t=q.front (); q.pop (); for (int i=0 ;i<4 ;i++) { int nxt_x=t.x+dx[i],nxt_y=t.y+dy[i]; if (nxt_x<1 ||nxt_x>n||nxt_y<1 ||nxt_y>n||map[nxt_x][nxt_y]=='1' ||dis[nxt_x][nxt_y]>0 ) continue ; q.push ((Point){nxt_x,nxt_y}); dis[nxt_x][nxt_y]=dis[t.x][t.y]+1 ; } } return ; } int main () { cin>>n; for (int i=1 ;i<=n;i++) for (int j=1 ;j<=n;j++) cin>>map[i][j]; cin>>start_x>>start_y>>final_x>>final_y; bfs (start_x,start_y); cout<<dis[final_x][final_y]; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <bits/stdc++.h> using namespace std;struct Point { int x,y; }; int n,m,x,y,dis[405 ][405 ];int dx[]={2 ,1 ,-2 ,1 ,-1 ,2 ,-2 ,-1 };int dy[]={1 ,2 ,1 ,-2 ,2 ,-1 ,-1 ,-2 };queue<Point> q; void bfs (int x,int y) { q.push ((Point){x,y}); dis[x][y]=0 ; while (!q.empty ()) { Point t=q.front (); q.pop (); for (int i=0 ;i<8 ;i++) { int nxt_x=t.x+dx[i],nxt_y=t.y+dy[i]; if (nxt_x<1 ||nxt_x>n||nxt_y<1 ||nxt_y>m||dis[nxt_x][nxt_y]!=-1 ) continue ; dis[nxt_x][nxt_y]=dis[t.x][t.y]+1 ; q.push ((Point){nxt_x,nxt_y}); } } return ; } int main () { memset (dis,-1 ,sizeof (dis)); cin>>n>>m>>x>>y; bfs (x,y); for (int i=1 ;i<=n;i++) { for (int j=1 ;j<=m;j++) cout<<setw (5 )<<dis[i][j]; cout<<endl; } return 0 ; }
P2895 Meteor Shower S
耗时 2 个月的巅峰对决,但最终还是我赢了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <bits/stdc++.h> #define int long long using namespace std;const int LEN=305 ;struct Point { int x,y; }; int m;int mp[LEN][LEN],dis[LEN][LEN];int dx[]={-1 ,0 ,1 ,0 },dy[]={0 ,1 ,0 ,-1 };queue<Point> q; int bfs () { q.push ((Point){0 ,0 }); dis[0 ][0 ]=0 ; while (!q.empty ()) { Point now=q.front (); q.pop (); for (int d=0 ;d<4 ;d++) { int nxt_x=now.x+dx[d],nxt_y=now.y+dy[d]; if (nxt_x<0 ||nxt_y<0 ) continue ; if (dis[nxt_x][nxt_y]) continue ; if (dis[now.x][now.y]+1 >=mp[nxt_x][nxt_y]) continue ; dis[nxt_x][nxt_y]=dis[now.x][now.y]+1 ; q.push ((Point){nxt_x,nxt_y}); if (mp[nxt_x][nxt_y]>1e9 ) return dis[nxt_x][nxt_y]; } } return -1 ; } signed main () { memset (mp,0x3f ,sizeof (mp)); cin>>m; while (m--) { int x,y,time; cin>>x>>y>>time; mp[x][y]=min (mp[x][y],time); for (int d=0 ;d<4 ;d++) { int nxt_x=x+dx[d],nxt_y=y+dy[d]; if (nxt_x<0 ||nxt_x>301 ||nxt_y<0 ||nxt_y>301 ) continue ; mp[nxt_x][nxt_y]=min (mp[nxt_x][nxt_y],time); } } cout<<bfs (); exit (0 ); }