BFS的题目没什么好说的,通常优化都是判断可行性,或者状压以后记忆化。几道例题都非常基础。
#10027. 「一本通 1.4 例 2」魔板
暴力写出置换即可。
#include <bits/stdc++.h> using namespace std; int buf[9],tar,ans,src; char vis[99999999]; map <int,string > sta; void A() { swap(buf[1],buf[5]); swap(buf[2],buf[6]); swap(buf[3],buf[7]); swap(buf[4],buf[8]); } void B() { int t1=buf[4], t2=buf[8]; buf[4]=buf[3]; buf[8]=buf[7]; buf[3]=buf[2]; buf[7]=buf[6]; buf[2]=buf[1]; buf[6]=buf[5]; buf[1]=t1; buf[5]=t2; } void C() { int t=buf[2]; buf[2]=buf[6]; buf[6]=buf[7]; buf[7]=buf[3]; buf[3]=t; } int compress() { int ret = 0; for(int i=1;i<=8;i++) ret=ret*10+buf[i]; return ret; } void depress(int x) { for(int i=8;i>=1;--i) buf[i]=x%10, x/=10; } int main() { for(int i=1;i<=8;i++) cin>>buf[i]; swap(buf[5],buf[8]); swap(buf[6],buf[7]); tar = compress(); for(int i=1;i<=4;i++) buf[i]=i; for(int i=1;i<=4;i++) buf[8-i+1]=i+4; src = compress(); queue <int> q; q.push(src); string v; sta[src]=v; vis[src]=1; while(!q.empty()) { int p = q.front(); q.pop(); if(p==tar) { cout<<vis[p]-1<<endl; for(int i=0;i<sta[p].size();i++) cout<<sta[p][i]; return 0; } int tmp; depress(p); A(); tmp=compress(); if(vis[tmp]==0) { vis[tmp]=vis[p]+1; sta[tmp]=sta[p]; sta[tmp]+="A"; q.push(tmp); } depress(p); B(); tmp=compress(); if(vis[tmp]==0) { vis[tmp]=vis[p]+1; sta[tmp]=sta[p]; sta[tmp]+="B"; q.push(tmp); } depress(p); C(); tmp=compress(); if(vis[tmp]==0) { vis[tmp]=vis[p]+1; sta[tmp]=sta[p]; sta[tmp]+="C"; q.push(tmp); } } }
#10028. 「一本通 1.4 例 3」Knight Moves
#include <bits/stdc++.h> using namespace std; const int dx[9] = {0,2,1,-1,-2,-2,-1,1,2}, dy[9] = {0,1,2,2,1,-1,-2,-2,-1}; int n,l,sx,sy,tx,ty; int f[305][305]; int main(){ cin>>n; while(n--) { cin>>l>>sx>>sy>>tx>>ty; memset(f,0xff,sizeof f); queue <pair<int,int> >q; q.push(make_pair(sx,sy)); f[sx][sy]=0; while(!q.empty()) { int px=q.front().first, py=q.front().second; q.pop(); if(px==tx && py==ty) { break; } else { for(int i=1;i<=8;i++) { int nx=px+dx[i], ny=py+dy[i]; if(nx<0 || ny<0 || nx>=l || ny>=l) continue; if(f[nx][ny] < 0) { f[nx][ny]=f[px][py]+1; q.push(make_pair(nx,ny)); } } } } cout<<f[tx][ty]<<endl; } }
#10029. 「一本通 1.4 练习 1」棋盘游戏
#include <bits/stdc++.h> using namespace std; struct Status { char a[4][4]; int compress() { int tmp = 0; for(int i=0;i<4;i++) for(int j=0;j<4;j++) tmp+=(a[i][j]-'0')*(1<<(i*4+j)); return tmp; } void depress(int tmp) { for(int i=0;i<4;i++) for(int j=0;j<4;j++) a[i][j]=((tmp>>(i*4+j))&1) + '0'; } }; const int d[12][4] = {{1,1,1,2},{1,2,1,3},{1,3,1,4},{2,1,2,2},{2,2,2,3},{2,3,2,4}, {3,1,3,2},{3,2,3,3},{3,3,3,4},{4,1,4,2},{4,2,4,3},{4,3,4,4}}; int f[100005]; int main() { Status st,en; for(int i=0;i<4;i++) { string str; cin>>str; for(int j=0;j<4;j++) st.a[i][j]=str[j]; } for(int i=0;i<4;i++) { string str; cin>>str; for(int j=0;j<4;j++) en.a[i][j]=str[j]; } int tar = en.compress(); int src = st.compress(); memset(f,0xff,sizeof f); f[src] = 0; queue <int> q; q.push(src); int cnt = 0; while(!q.empty()) { int p = q.front(); q.pop(); if(p==tar) break; Status s; for(int i=0;i<12;i++) { s.depress(p); swap(s.a[d[i][0]-1][d[i][1]-1],s.a[d[i][2]-1][d[i][3]-1]); int tmp = s.compress(); if(f[tmp]<0) { f[tmp]=f[p]+1; q.push(tmp); } } for(int i=0;i<12;i++) { s.depress(p); swap(s.a[d[i][1]-1][d[i][0]-1],s.a[d[i][3]-1][d[i][2]-1]); int tmp = s.compress(); if(f[tmp]<0) { f[tmp]=f[p]+1; q.push(tmp); } } } cout<<f[tar]<<endl; }
#10030. 「一本通 1.4 练习 2」Keyboarding
一开始题目看错了WA了好几发
#include <bits/stdc++.h> using namespace std; struct Status { int x,y,z; int compress() { return z*2500+y*50+x; } void decompress(int tmp) { x=tmp%50; y=(tmp/50)%50; z=tmp/2500; } }; const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; int r,c; string s,tab[55]; int f[26000005]; pair<int,int> g[55][55][4]; int main() { cin>>r>>c; for(int i=0;i<r;i++) cin>>tab[i]; cin>>s; s+="*"; for(int j=0;j<r;j++) for(int k=0;k<c;k++) { for(int l=0;l<4;l++) { int x=j,y=k; int me=tab[j][k]; while(x>=0&&y>=0&&x<r&&y<c&&me==tab[x][y]) x+=dx[l],y+=dy[l]; if(x<0)x=j; if(y<0)y=k; if(x>=r)x=j;if(y>=c)y=k; g[j][k][l]=make_pair(x,y); } } memset(f,0xff,sizeof f); f[0]=0; queue <int> q; int len = s.length(); int cnt = 0; q.push(0); while(!q.empty()) {++cnt; int p=q.front(); q.pop(); Status st; st.decompress(p); char me = tab[st.x][st.y]; if(st.z==len) { cout<<f[p]<<endl; return 0; } for(int i=0;i<4;i++) { st.decompress(p); pair<int,int> to = g[st.x][st.y][i]; st.x=to.first; st.y=to.second; int tmp=st.compress(); if(f[tmp]<0) { f[tmp]=f[p]+1; q.push(tmp); } } st.decompress(p); if(tab[st.x][st.y]==s[st.z]) { st.z++; int tmp=st.compress(); f[tmp]=f[p]+1; q.push(tmp); } } //cout<<cnt<<endl; }
#10031. 「一本通 1.4 练习 3」移动玩具
#include <bits/stdc++.h> using namespace std; struct Status { char a[4][4]; int compress() { int tmp = 0; for(int i=0;i<4;i++) for(int j=0;j<4;j++) tmp+=(1<<(i*4+j))*(a[i][j]-'0'); return tmp; } void decompress(int tmp) { for(int i=0;i<4;i++) for(int j=0;j<4;j++) a[i][j] = ((tmp>>(i*4+j))&1) + '0'; } }; int f[100005]; const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; int main() { Status St,En; int st,en; for(int i=0;i<4;i++) { string tmp; cin>>tmp; for(int j=0;j<4;j++) St.a[i][j]=tmp[j]; } for(int i=0;i<4;i++) { string tmp; cin>>tmp; for(int j=0;j<4;j++) En.a[i][j]=tmp[j]; } st = St.compress(); en = En.compress(); memset(f,0xff,sizeof f); queue <int> q; q.push(st); f[st]=0; while(q.size()) { int p = q.front(); q.pop(); if(p==en) { cout<<f[p]<<endl; return 0; } Status s; s.decompress(p); for(int i=0;i<4;i++){ for(int j=0;j<4;j++) { if(s.a[i][j]=='0') continue; for(int l=0;l<4;l++) { int nx=i+dx[l],ny=j+dy[l]; if(nx<0||ny<0||nx>3||ny>3) continue; if(s.a[nx][ny]=='1') continue; swap(s.a[nx][ny],s.a[i][j]); int tmp = s.compress(); if(f[tmp]==-1) { f[tmp]=f[p]+1; q.push(tmp); } swap(s.a[nx][ny],s.a[i][j]); } } } } }