周六900C++班级2022-11-12-搜索练习
部分和问题
#include<bits/stdc++.h> #include<iostream> using namespace std; int k,n,m,num,vis[1042],dt[1000],f; void dfs(){ if(f==1)return; if(num==k){ f=1; return; } for(int i=1;i<=n;i++){ if(vis[i]==0&&num+dt[i]<=k){ vis[i]=1; num+=dt[i]; dfs(); vis[i]=0; num-=dt[i]; } } }; int main(){ while(cin>>n>>k){ for(int i=1;i<=n;i++){ cin>>dt[i]; } memset(vis,0,sizeof(0)); f=0;num=0; dfs(); if(f)cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
LETTERS
#include<bits/stdc++.h> using namespace std; int vis[21][21]; int visc[26]; //标记字母是否走过 char a[21][21]; //地图a int nex[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; //右下左上方向数组 int n,m,ans,step; //ans是最长,step是当前步数 void dfs(int x,int y) { ans = max(ans,step); //ans实时获取最大步长 for(int i=0;i<4;i++) { int tx = x + nex[i][0]; int ty = y + nex[i][1]; if(tx<1||tx>n||ty<1||ty>m)continue; if(vis[tx][ty]==0&&visc[a[tx][ty]-'A']==0)//vis标记地图,visc标记字母 { vis[tx][ty] = 1; visc[a[tx][ty]-'A'] = 1; step++; dfs(tx,ty); vis[tx][ty] = 0; visc[a[tx][ty]-'A'] = 0; step--; } } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; vis[1][1] = visc[a[1][1]-'A'] = 1; //起点标记 step = 1; //起点的步长从1开始 dfs(1,1); //起点传入,开搜 cout<<ans; return 0; }
Knight Moves
#include<bits/stdc++.h> using namespace std; int nex[8][2] = {{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}}; //方向数组 int vis[310][310]; //标记数组 int n,m,f,ans,sx,sy,ex,ey; struct node{ int x,y,step; //step步长 }; node q[90005]; void bfs(int sx,int sy) { int head = 1,tail = 1; //队首head,队尾tail q[tail].x = sx; q[tail].y = sy; q[tail].step = 0; //13行-15行:起点入队 tail++; //队尾扩充 vis[sx][sy] = 1; //标记起点 while(head<tail) { for(int i=0;i<8;i++) //循环队首head的8个方向 { int tx = nex[i][0] + q[head].x; //下一步坐标tx = 第i个方向+队首head的x坐标 int ty = nex[i][1] + q[head].y; if(tx<0||tx>=n||ty<0||ty>=n)continue; if(vis[tx][ty]==0) //tx,ty没有标记过 { //标记入队并扩充队列长度 vis[tx][ty] = 1; q[tail].x = tx; q[tail].y = ty; q[tail].step = q[head].step + 1; tail++; } if(tx==ex && ty==ey){ //判断下一步是否是终点 f = 1; //终点标记f = 1 ans = q[tail-1].step; break; } } if(f)break; head++; } } int main() { int t; //t组数据 cin>>t; while(t--) //处理t组数据 { cin>>n>>sx>>sy>>ex>>ey; //输入地图大小和起点终点 memset(vis,0,sizeof(vis)); //初始化标记数组为0 f = 0;ans = 0; if(sx==ex && sy==ey){ //起点为终点 cout<<0<<endl; continue; } bfs(sx,sy); //将起点传入开搜 cout<<ans<<endl; } return 0; }
Bad Grass
#include<bits/stdc++.h> using namespace std; int ma[1005][1005]; int vis[1005][1005]; int nex[8][2]={{0,1},{1,0},{0,-1},{-1,0},{-1,1},{1,1},{1,-1},{-1,-1}}; int n,m,f,ans,sx,sy,ex,ey; void dfs(int x,int y){ for(int i=0;i<8;i++){ int tx=x+nex[i][0]; int ty=y+nex[i][1]; //下一步tx,ty if(tx<1||tx>n||ty<1||ty>m)continue; //越界判断 if(ma[tx][ty]!=0&&vis[tx][ty]==0){ //如果下一步tx,ty地图上不是0并且没vis标记过 vis[tx][ty]=1; //vis标记tx,ty dfs(tx,ty); //继续搜索相邻点 } } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>ma[i][j]; //输入地图 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) //循环地图 if(ma[i][j]!=0&&vis[i][j]==0){ //找到地图上非0点且没标记过 vis[i][j]=1; ans++; //岛数量+1 dfs(i,j); //把i,j点相邻的点全部标记 } cout<<ans; return 0; }