[kuangbin带你飞]专题一 简单搜索 (17/1000)
来源:互联网 发布:万国数据fm经理待遇 编辑:程序博客网 时间:2024/06/05 14:21
终于,做完了kuangbin大神带你飞的专题一之简单搜索,实在有一股无法言喻的感觉,每道题类型都差不多但细节实现却有点细微区别,所以14道题我就只当作5题了。。
棋盘问题
稍微变了点形的皇后问题,不能一行一行搜索,要一个一个格子搜索
include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N=10;int n,k,ans;int R[N],C[N],a[N][N];char ch;void dfs(int row,int col,int num){ int NR,NC; if (num==k+1) { ans++; return; } if(row!=n){ NC=col+1; NR=row; if (NC==n) { NC=0; NR++; } if(!a[row][col]&&!R[row]&&!C[col]){ R[row]=1; C[col]=1; dfs(NR,NC,num+1); C[col]=0; R[row]=0; dfs(NR,NC,num); } else dfs(NR,NC,num); } }int main(){ while(cin>>n>>k){ if (n==-1&&k==-1) return 0; ans=0; memset(a,0,sizeof(a)); memset(R,0,sizeof(R)); memset(C,0,sizeof(C)); for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cin>>ch; if (ch=='.'){ a[i][j]=1; } else if (ch=='#') { a[i][j]=0; } } } dfs(0,0,1); cout<<ans<<endl; } return 0;}
Dungeon Master
三维BFS
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>#include <set>const int N=30+10;using namespace std;struct state{ int z,x,y,step;};queue<state> Q;set<int> S;int L,R,C,goalx,goaly,goalz,X,Y,Z,code;char tmp;int dx[6]={1,-1,0,0,0,0}, dy[6]={0,0,1,-1,0,0}, dz[6]={0,0,0,0,1,-1};int a[N][N][N];void bfs(){ while(!Q.empty()){ state t=Q.front();Q.pop(); for(int i=0;i<6;i++){ X=t.x+dx[i]; Y=t.y+dy[i]; Z=t.z+dz[i]; if (a[Z][X][Y]==1||X<0||X>=R||Z<0||Z>=L||Y<0||Y>=C) continue; code=10000*Z+100*X+Y; if (X==goalx&&Y==goaly&&Z==goalz){ cout<<"Escaped in "<<t.step+1<<" minute(s)."<<endl; return; } if (S.find(code)==S.end()){ S.insert(code); state node={Z,X,Y,t.step+1}; Q.push(node); } } } cout<<"Trapped!"<<endl;}int main(){ while(cin>>L>>R>>C){ if (!L&&!R&&!C) break; memset(a,0,sizeof(a)); S.clear(); while(!Q.empty()) Q.pop(); for(int i=0;i<L;i++){ for(int j=0;j<R;j++){ for(int k=0;k<C;k++){ cin>>tmp; if(tmp=='S'){ state first={i,j,k,0}; Q.push(first); code=10000*i+100*j+k; S.insert(code); a[i][j][k]=0; } else if(tmp=='E'){ goalz=i; goalx=j; goaly=k; a[i][j][k]=0; } else if(tmp=='#'){ a[i][j][k]=1; } else if(tmp=='.'){ a[i][j][k]=0; } } } } bfs(); } return 0;}
Catch That Cow
BFS,数字变换,反过来找,能稍微剪一下枝
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <set>#include <queue>using namespace std;struct node{ int num,step;};int n,k,T,Step;int main(){ cin>>n>>k; if (n==k){ cout<<0<<endl; return 0; } queue<node> Q; set<int> S; node first={k,0}; Q.push(first); S.insert(k); while(!Q.empty()){ node t=Q.front();Q.pop(); for(int i=0;i<3;i++){ if (i==0) T=t.num+1; else if (i==1) T=t.num-1; else if ((i==2)&&(t.num%2==0)) T=t.num/2; Step=t.step+1; if (S.find(T)!=S.end()) continue; if (T==n){ cout<<Step<<endl; return 0; } node t1={T,Step}; Q.push(t1); S.insert(T); } } return 0;}
Fliptile
二进制枚举,位运算,只用枚举第一行就能确定整个棋盘的翻转情况
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>const int N=20+10;const int INF=0x3f3f3f3f;using namespace std;int dx[4]={0,0,-1,1}, dy[4]={-1,1,0,0};int n,m,k,tmp,ok,ans=INF,cnt;int a[N][N],vis[N][N],opr[N][N];void turn(int x,int y){ int X,Y; a[x][y]=a[x][y]^1; for(int i=0;i<4;i++){ X=x+dx[i]; Y=y+dy[i]; if (X<0||X>=n||Y<0||Y>=m) continue; a[X][Y]=a[X][Y]^1; }}int check(int r){ for(int i=0;i<m;i++){ if (a[r][i]) return 0; } return 1;}int main(){ cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>a[i][j]; } } for(int i=0;i<=(1<<m)-1;i++){ cnt=0; memset(vis,0,sizeof(vis)); for(int j=0;j<m;j++){ k=1<<j; tmp=k&i; if (tmp) { vis[0][m-1-j]=1; turn(0,m-1-j); cnt++; } } /*cout<<endl; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<a[i][j]<<' '; } cout<<endl; }*/ for(int i=1;i<n;i++){ for(int j=0;j<m;j++){ if (a[i-1][j]) { turn(i,j); vis[i][j]=1; cnt++; } } } if (check(n-1)) { if (cnt<ans){ ans=cnt; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ opr[i][j]=vis[i][j]; } } } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if (vis[i][j]) turn(i,j); } } } if (ans==INF) cout<<"IMPOSSIBLE"<<endl; else { for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<opr[i][j]<<' '; } cout<<endl; } } return 0;}
Find The Multiple
依旧是反过来找,正难则反,深搜要自己限定深度,或用bfs
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>typedef unsigned long long ull;typedef long long ll;using namespace std;int n,ok;ull ans;void ids(ull num,int k,int dep){ if (ok==1) return; if (num%n==0) { ans=num; ok=1; return; } if (k==dep) return; ids(num*10,k+1,dep); ids(num*10+1,k+1,dep);}int main(){ while(cin>>n){ if (!n) break; ok=0; ids(1,1,19); if (ok) cout<<ans<<endl; } return 0;}
Prime path
关键是数位的枚举
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>#include <set>using namespace std;const int N=10000+10;struct node{ int num,step;};int t,n,m,tmp,Step,Num,number;int prime[N];void bfs(){ cin>>n>>m; if (n==m){ cout<<0<<endl; return; } queue<node> Q; set<int> S; node first={n,0}; Q.push(first); S.insert(n); while(!Q.empty()){ node t=Q.front();Q.pop(); for(int i=1;i<=1000;i*=10){ tmp=t.num / i % 10; number=t.num-tmp*i; Step=t.step+1; for(int j=0;j<=9;j++){ Num=number+j*i; //cout<<Num<<endl; if (!prime[Num]||S.find(Num)!=S.end()||Num<1000) continue; //cout<<Num<<endl; if (Num==m){ cout<<Step<<endl; return; } node t1={Num,Step}; Q.push(t1); S.insert(Num); } } }}int main(){ for(int i=2;i<=9999;i++) prime[i]=1; for(int i=2;i<=9999;i++){ if (prime[i]){ for(int j=i*i;j<=9999;j+=i){ prime[j]=0; } } } cin>>t; while(t--) bfs(); return 0;}
Shuffle’m Up
模拟题,体会一下模拟与搜索的区别
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <string>#include <set>using namespace std;int t,len,step,kase;string s1,s2,s3;set<string> S;int main(){ cin>>t; while(t--){ kase++; cin>>len; cin>>s1>>s2>>s3; step=0; while(1){ step++; string tmp=""; for(int i=0;i<len;i++){ tmp+=s2[i]; tmp+=s1[i]; } //cout<<tmp<<endl; if (S.find(tmp)!=S.end()){ cout<<kase<<' '<<-1<<endl; break; } S.insert(tmp); if (tmp==s3) { cout<<kase<<' '<<step<<endl; break; } s1=""; s2=""; for(int i=0;i<len;i++){ s1+=tmp[i]; } for(int i=len;i<2*len;i++){ s2+=tmp[i]; } } } return 0;}
Pots
倒水问题+记录路径
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <string>#include <queue>const int N=100+10;using namespace std;string str[6]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};struct node{ int a,b; string s;};void print(string st){ cout<<st.length()<<endl; for(int i=0;i<st.length();i++){ cout<<str[st[i]-'0']<<endl; }}int A,B,C;int vis[N][N];int main(){ cin>>A>>B>>C; queue<node> Q; Q.push((node){0,0}); vis[0][0]=1; while(!Q.empty()){ node t=Q.front();Q.pop(); for(int i=0;i<6;i++){ node tmp=t; //cout<<tmp.a<<' '<<tmp.b<<endl; if (i==0){ tmp.a=A; tmp.s+='0'; } else if (i==1){ tmp.b=B; tmp.s+='1'; } else if (i==2){ tmp.a=0; tmp.s+='2'; } else if (i==3){ tmp.b=0; tmp.s+='3'; } else if (i==4){ if (tmp.a+tmp.b<=B){ tmp.b+=tmp.a; tmp.a=0; } else { tmp.a=tmp.a-(B-tmp.b); tmp.b=B; } tmp.s+='4'; } else if (i==5){ if (tmp.b+tmp.a<=A){ tmp.a+=tmp.b; tmp.b=0; } else { tmp.b=tmp.b-(A-tmp.a); tmp.a=A; } tmp.s+='5'; } //cout<<tmp.a<<' '<<tmp.b<<endl<<endl; if (vis[tmp.a][tmp.b]) continue; if (tmp.a==C||tmp.b==C){ print(tmp.s); return 0; } Q.push(tmp); vis[tmp.a][tmp.b]=1; } } cout<<"impossible"<<endl; return 0;}
Fire Game
用cnt记录草数,可判断是否全部稍晚,还有一个小技巧是,一开始队列入两个着火点
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>const int N=10+10;const int INF=0x3f3f3f3f;using namespace std;struct node{ int x,y; };int dx[4]={0,0,-1,1}, dy[4]={-1,1,0,0};int t,n,m,ans,kase,cnt,now,X,Y,tmp;int T[N][N],a[N][N];char ch;void bfs(int A,int b,int c,int d){ //cout<<A<<b<<c<<d<<endl; now=2; if (A==c&&b==d) now--; tmp=0; memset(T,-1,sizeof(T)); queue<node> Q; Q.push((node){A,b});T[A][b]=0; Q.push((node){c,d});T[c][d]=0; while(!Q.empty()){ node t=Q.front();Q.pop(); for(int i=0;i<4;i++){ X=t.x+dx[i]; Y=t.y+dy[i]; if (X<0||X>=n||Y<0||Y>=m) continue; if (!a[X][Y]) continue; if (T[X][Y]!=-1) continue; now++; Q.push((node){X,Y}); T[X][Y]=T[t.x][t.y]+1; tmp=max(T[X][Y],tmp); } } if (now==cnt) ans=min(tmp,ans);}int main(){ cin>>t; while(t--){ cin>>n>>m; ans=INF; kase++; cnt=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>ch; if (ch=='.') a[i][j]=0; else { cnt++; a[i][j]=1; } } } for(int i=0;i<n;i++) for(int j=0;j<m;j++) for(int k=0;k<n;k++) for(int L=0;L<m;L++) if (a[i][j]&&a[k][L]){ bfs(i,j,k,L); } /*for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<T[i][j]<<' '; } cout<<endl; }*/ if (ans==INF) ans=-1; cout<<"Case "<<kase<<": "<<ans<<endl; } return 0;}
Fire!
坑点在着火点可能不止一个
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>const int N=1000+10;using namespace std;struct node{ int x,y;};int dx[4]={0,0,-1,1}, dy[4]={-1,1,0,0};char tmp;int t,n,m,x1,y1,x2,y2,flag,X,Y;int a[N][N],vis[N][N],D[N][N],T[N][N];void bfs(int x,int y){ queue<node> Q; memset(vis,0,sizeof(vis)); node first={x,y}; Q.push(first); vis[x][y]=1; while(!Q.empty()){ node t=Q.front();Q.pop(); for(int i=0;i<4;i++){ X=t.x+dx[i]; Y=t.y+dy[i]; if (X<0||X>=n||Y<0||Y>=m) { if (flag==0){ cout<<D[t.x][t.y]+1<<endl; return; } else continue; } if (vis[X][Y]) continue; if (a[X][Y]) continue; if (flag) { if (T[t.x][t.y]+1>=T[X][Y]) continue; T[X][Y]=T[t.x][t.y]+1; } else { if (D[t.x][t.y]+1>=T[X][Y]) continue; D[X][Y]=D[t.x][t.y]+1; } node t1={X,Y}; Q.push(t1); vis[X][Y]=1; } } if (flag==0) cout<<"IMPOSSIBLE"<<endl;}int main(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); cin>>t; while(t--){ memset(a,0,sizeof(a)); memset(T,0x3f,sizeof(T)); memset(D,0,sizeof(D)); cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>tmp; if (tmp=='J'){ x2=i; y2=j; } else if (tmp=='F'){ T[i][j]=0; } else if(tmp=='#'){ a[i][j]=1; } } } flag=1; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if (T[i][j]==0) bfs(i,j); } } flag=0; bfs(x2,y2); /*for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<T[i][j]<<' '; } cout<<endl; } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<D[i][j]<<' '; } cout<<endl; }*/ } return 0;}/*24 4#####JF##..##..#3 3####J.#.F */
迷宫问题
如何记录路径,这是个问题,可以开两个二维数组记录上一个位置在那里,或者用开一个结构体数组保存,或者用string记录
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <set>#include <queue>const int N=5+5;using namespace std;struct node{ int x,y,step;};int dx[4]={0,0,-1,1}, dy[4]={-1,1,0,0};int code,Nx,Ny,Ns;int a[N][N],Lx[N][N],Ly[N][N];set<int> S;queue<node> Q;void print(int x,int y){ if(x==-1&&y==-1) return; print(Lx[x][y],Ly[x][y]); printf("(%d, %d)\n",x,y);}int main(){ for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ cin>>a[i][j]; } } code=0; S.insert(code); node first={0,0,0}; Q.push(first); Lx[0][0]=-1; Ly[0][0]=-1; while(!Q.empty()){ node tmp=Q.front();Q.pop(); for(int i=0;i<4;i++){ Nx=tmp.x+dx[i]; Ny=tmp.y+dy[i]; Ns=tmp.step+1; if (Nx<0||Nx>=5||Ny<0||Ny>=5||a[Nx][Ny]) continue; code=10*Nx+Ny; if(S.find(code)==S.end()){ node t={Nx,Ny,Ns}; Lx[Nx][Ny]=tmp.x; Ly[Nx][Ny]=tmp.y; Q.push(t); S.insert(code); } if(Nx==4&&Ny==4){ print(4,4); return 0; } } } return 0;}
Oil Deposits
联通块问题
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>const int N=100+10;using namespace std;char tmp;int n,m,cnt;int a[N][N],vis[N][N];int dx[8]={-1,-1,-1, 0, 0, 1, 1, 1}, dy[8]={-1, 0, 1,-1, 1,-1, 0, 1};void dfs(int x,int y){ int x1,y1; vis[x][y]=1; for(int i=0;i<8;i++){ x1=x+dx[i]; y1=y+dy[i]; if (a[x1][y1]&&!vis[x1][y1]&&x1>=0&&x1<n&&y1>=0&&y1<m) dfs(x1,y1); }}int main(){ while(1){ cin>>n>>m; if (!n&&!m) break; cnt=0; memset(a,0,sizeof(a)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>tmp; if (tmp=='@') a[i][j]=1; else a[i][j]=0; } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if (a[i][j]&&!vis[i][j]) { cnt++; dfs(i,j); } } } cout<<cnt<<endl; } return 0;}
非常可乐
倒水问题,很明显S需要是偶数,这里可以稍微剪一下枝
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>const int N=100+10;using namespace std;struct node{ int v[3],step;};int m[3],t1[3],s,vis[N][N][N];int ok(int a,int b,int c){ if (a==b&&c==0) return 1; if (a==c&&b==0) return 1; if (b==c&&a==0) return 1; return 0;}void bfs(){ memset(vis,0,sizeof(vis)); queue<node> Q; node first={0,0,m[2],0}; Q.push(first); vis[0][0][m[2]]=1; while(!Q.empty()){ node t=Q.front();Q.pop(); s=t.step+1; for(int i=0;i<3;i++){ if (!t.v[i]) continue; for(int j=0;j<3;j++){ if (i!=j&&t.v[j]<m[j]){ for(int i=0;i<3;i++) t1[i]=t.v[i]; if (t.v[i]+t.v[j]<=m[j]){ t1[j]=t1[i]+t1[j]; t1[i]=0; } else{ t1[i]=t1[i]-(m[j]-t1[j]); t1[j]=m[j]; } if (vis[t1[0]][t1[1]][t1[2]]) continue; if (ok(t1[0],t1[1],t1[2])) { cout<<s<<endl; return; } node T={t1[0],t1[1],t1[2],s}; Q.push(T); vis[t1[0]][t1[1]][t1[2]]=1; } } } } cout<<"NO"<<endl;}int main(){ while(1){ scanf("%d%d%d",&m[2],&m[0],&m[1]); if (!m[0]&&!m[1]&&!m[2]) break; if (m[2]%2){ cout<<"NO"<<endl; continue; } bfs(); } return 0;}
Find a way
要注意有些KFC是不能到达的
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>#include <set>const int N=200+10;using namespace std;char tmp;int n,m,k,code,x1,y1,x2,y2,X,Y,ans,flag,cnt;int a[N][N],D[N][N],D1[N][N];int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};struct node{ int x,y;};queue<node> Q;set<int> S;void bfs(){ while(!Q.empty()&&k<cnt){ node t=Q.front();Q.pop(); for(int i=0;i<4;i++){ X=t.x+dx[i]; Y=t.y+dy[i]; if (X<0||X>=n||Y<0||Y>=m||a[X][Y]==1) continue; code=1000*X+Y; if (S.find(code)==S.end()){ node t1={X,Y}; Q.push(t1); S.insert(code); if (flag==0) D[X][Y]=D[t.x][t.y]+1; else D1[X][Y]=D1[t.x][t.y]+1; if (a[X][Y]==2) k++; } } }}int main(){ while(cin>>n>>m){ cnt=0; memset(a,0,sizeof(a)); memset(D,0,sizeof(D)); memset(D1,0,sizeof(D1)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>tmp; if (tmp=='Y') { x1=i; y1=j; } else if (tmp=='M'){ x2=i; y2=j; } else if (tmp=='@'){ a[i][j]=2; cnt++; } else if (tmp=='#'){ a[i][j]=1; } } } while (!Q.empty()) Q.pop(); S.clear(); node first={x1,y1}; Q.push(first); S.insert(1000*x1+y1); k=0; flag=0; bfs(); /*for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<D[i][j]<<' '; } cout<<endl; }*/ while (!Q.empty()) Q.pop(); S.clear(); node first1={x2,y2}; Q.push(first1); S.insert(1000*x2+y2); k=0; flag=1; bfs(); /*for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<D1[i][j]<<' '; } cout<<endl; }*/ ans=0x3f3f3f3f; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if (a[i][j]==2&&D[i][j]&&D1[i][j]) ans=min(ans,D[i][j]+D1[i][j]); } } cout<<ans*11<<endl; } return 0;}
阅读全文
0 0
- [kuangbin带你飞]专题一 简单搜索 (17/1000)
- [kuangbin神带你飞]专题一 简单搜索
- kuangbin带你飞 专题一 简单搜索 (题解)
- Fire Game [kuangbin带你飞]专题一 简单搜索
- [kuangbin带你飞]专题一 简单搜索 总结
- Kuangbin带你飞专题一 简单搜索
- [kuangbin带你飞]专题一 简单搜索 D - Fliptile
- [kuangbin带你飞]专题一 简单搜索-J - Fire!
- [kuangbin带你飞]专题一 简单搜索 - H - Pots
- [kuangbin带你飞]专题一 简单搜索 A POJ1321
- [kuangbin带你飞]专题一 简单搜索 B POJ2251
- [kuangbin带你飞]专题一 简单搜索 C POJ3278
- [kuangbin带你飞]专题一 简单搜索 D poj3279
- [kuangbin带你飞]专题一 简单搜索 E POJ1426
- [kuangbin带你飞]专题一 简单搜索 F POJ3126
- [kuangbin带你飞]专题一 简单搜索 H POJ3414
- [kuangbin带你飞]专题一 简单搜索 G POJ3087
- [kuangbin带你飞]专题一 简单搜索 Fliptile :dfs
- vlan是什么?怎么创vlan?
- 基于XGBoost的特征选择原理与实战
- 后端解决跨域问题
- java中的字符串以及java中常用的系统方法
- Java面试题整理
- [kuangbin带你飞]专题一 简单搜索 (17/1000)
- react 入门-创建组件(1)继承component法
- docker python 提示错误UnicodeEncodeError: 'ascii' codec can't encode characters in position
- Set和Map数据结构
- 学习日志2017.12.13
- 路由远程配置命令-Smallbaal的博客
- 互联网时代下的十大商业模式
- Linux学习之文件系统与文件系统的压缩与打包
- 快速了解JavaScript