思路:
简单的BFS但是有两个坑点:
1.找到过的字母,要当连通的点处理
2.可能只有字母A
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
typedef struct{
int x,y;
}Node ;
map <char,Node> mark;
bool vis[15][15];
int dir_x[]={-1,0,0,1},
dir_y[]={0,1,-1,0};
bool vis1[15][15];
char maze[15][15];
int bfs(char st,char en){
//cout<<"st:"<<endl<<mark[st].x<<' '<<mark[st].y<<endl;
for(int i=0;i<=14;i++)
for(int j=0;j<=14;j++)
vis1[i][j]=vis[i][j];//每次用过的图要刷新一遍,这是一个图多次bfs常用的手段
int ans=1;bool flag=1;
Node temp,now,point;
temp.x=mark[st].x;temp.y=mark[st].y;
point.x=0;point.y=0;//Node point作为每层bfs的分界线,或者在定义Node时加入一个变量以表示层数
queue <Node> que;
while(!que.empty()) que.pop();
que.push(temp);
while(!que.empty()){//bfs正文
if(flag){que.push(point);flag=0;}
temp=que.front();que.pop();
if(temp.x==0&&temp.y==0){ans++;flag=1;continue;};
for(int i=0;i<4;i++){
now.x=temp.x+dir_x[i];
now.y=temp.y+dir_y[i];
if(maze[now.x][now.y]==en){
vis[mark[st].x][mark[st].y]=0;
vis[mark[en].x][mark[en].y]=0;
return ans;
}
else if(!vis1[now.x][now.y]){
vis1[now.x][now.y]=1;
que.push(now);
//cout<<ans<<endl<<now.x<<' '<<now.y<<endl;
}
}
}
return 0;
}
int solve(int sum){
int ans=0,temp;
for(int i=1;i<sum;i++){//从A到Z逐项求bfs
temp=bfs('A'+i-1,'A'+i);
if(temp==0) return 0;
ans+=temp;
//cout<<ans<<endl;
}
return ans;
}
int main()
{
int t,n;
cin>>t;
getchar();
for(int asd=1;asd<=t;asd++){
int ans=0,sum=0;
char mdzz[150];
gets(mdzz);
cin>>n;getchar();
memset(vis,1,sizeof(vis));
memset(vis1,1,sizeof(vis1));
memset(maze,0,sizeof(maze));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%c",&maze[i][j]);
if(maze[i][j]>='A'&&maze[i][j]<='Z'){
sum++;//统计字母个数
mark[maze[i][j]].x=i;
mark[maze[i][j]].y=j;
}
else if(maze[i][j]=='.')