就是按照A->B->C->D....去拿,求步数;
思路:
有一个注意点:如果碰到合法字母吃掉,再以后的某次可以重新到改点;
BFS的因为标记而减少了重复位置的到达,但是按照题目,窝从A->B吃了B以后,我后面还是要以合法并且最短的方法到C,所以...
有一种方法,就是我BFS最多26次,每次走个A->B/B->C/C->D/.../Y->Z,一步一步走;还有就是搞一个BFS,然后中间初始化一下就好了。
总的还是相同的。
这道题目深刻地理解BFS就是起点到终点的一个过程~(●'◡'●)也像走一步再走一步
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int>PII; const double eps=1e-5; const double pi=acos(-1.0); const int mod=1e9+7; const int INF=0x3f3f3f3f; char ma[15][15]; bool vis[15][15]; int dx[4]={0,0,-1,1}; int dy[4]={1,-1,0,0}; int n; struct asd{ int x,y; int step; }; int main() { int T,cas=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s",ma[i]); bool flag; int flat=0;//记录终点字母; int sx,sy; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(ma[i][j]=='A') { sx=i; sy=j; } if(ma[i][j]>='A'&&ma[i][j]<='Z') { if(ma[i][j]>flat) flat=ma[i][j]; } } } printf("Case %d: ",cas++); if(!flat) { puts("Impossible"); continue; } memset(vis,0,sizeof(vis)); queue<asd>q; while(!q.empty()) q.pop(); asd now,ne; int ans,num; now.x=sx; now.y=sy; now.step=0; vis[sx][sy]=1; num=1; ans=0; flag=false; q.push(now); while(!q.empty()) { now=q.front(); q.pop(); if(ma[now.x][now.y]==('A'+num)) { ans+=now.step; if(flat==('A'+num)) //如果是终点,再见; { flag=true; break; } num++; //初始化,以这个点为起点,搜下一个字母; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); now.step=0; vis[now.x][now.y]=1; } for(int i=0;i<4;i++) { int x=now.x+dx[i]; int y=now.y+dy[i]; if(x<0||y<0||x>=n||y>=n||vis[x][y]||ma[x][y]=='#'||ma[x][y]>('A'+num)) continue; vis[x][y]=1; ne.x=x; ne.y=y; ne.step=now.step+1; q.push(ne); } } if(flag||flat=='A') printf("%d ",ans); else puts("Impossible"); } return 0; } /* 2 CB .A 3 A.. .BD #C# */