hnust - BFS_连连看游戏 - BFS

题目描述

大家都玩过连连看吧!今天我们玩一个类似的游戏。在一个由10*10个小方格组成的矩形里有n(n<=10)对字符(它们是大写字符中的前n个)。矩形里有些位置是可以从上面走过,有些则不能。能走过的位置用’.’标识,不能的用’#’标识。如果2个相同字符是连通的(从一个字符能走到另一个字符,注意走的时候只能向上、下、左、右走。某个位置是有其他字符时,这个位置是不能走的),那么这对字符能够进行配对。如果将这对字符配对,这对字符将从这个矩形里消除,也就是说这2个字符所在的位置对于其他字符而言变成能走动了。
现在的问题是:请你决定这些字符的配对顺序(只有能配对才能进行配对),使得n对字符最后都配对成功。

输入

先给出一个正整数t(t<=10),表示有t组测试数据。
每组测试数据有10行组成,每行有10个字符。这些字符只能是’.’,’#’,或者是大写字符中的前n个。每组测试数据中不超过10对字符。

输出

如果能够使每组测试数据中的n对字符配对成功,输出配对的顺序。如果有多种配对成功的顺序,输出字典序最小的那组。
否则输出”My God!”。

样例输入

2
ABF…….
CE……..
D………
……….
……….
……….
……….
………D
……..EC
…….FBA
ABF…….
CE……..
D………
……….
……….
………#
……..#D
………#
……..EC
…….FBA

样例输出

DCABEF
My God!

题解

  • 显然用BFS(广度优先搜索)。
  • 一个暴力的思路就是选中一个字符然后对它进行广度优先搜索,遇到#遇到其他字符停止。
  • 用map存储字符的一个位置,因为map红黑树,按字典序在内部自动排序,我们只要循环调用迭代器iterator即可完成单个搜索。但这里要注意的是,如果map一开始为空要提前预判。
  • 判重用vis[][];该位置来过则标记为true。尽可能减少重复搜索次数。
#include 
#include 
#include 
#include 
#include 
using namespace std;

struct Node
{
    int x;
    int y;
}que[105];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
char mmp[11][11];
bool vis[11][11];
bool bfs(char c,Node p)
{
    memset(vis,0,sizeof(vis));
    //queue que; que.push(p);
    int front=1,rear=1;
    que[rear++]=p;
    vis[p.x][p.y]=1;
    while(front//Node q=que.front();que.pop();
        Node q=que[front++];
        for(int i=0;i<4;i++){
            int x=q.x+dir[i][0],y=q.y+dir[i][1];
            if(x>=0&&x<10&&y>=0&&y<10&&!vis[x][y]){
                if(mmp[x][y]==c){
                    mmp[x][y]=mmp[p.x][p.y]='.';
                    return true;
                }else if(mmp[x][y]=='.'){
                    Node t;t.x=x;t.y=y;
                    vis[x][y]=1;
                    que[rear++]=t;
                    //que.push(t);
                }
            }
        }
    }
    return false;
}
int main()
{
    //freopen("E:\\debug.txt","r",stdin);
    int T;
    scanf("%d",&T);
    char ans[50];
    int cnt;
    while(T--){
        cnt=0;
        map<char,Node> m;
        map<char,Node>::iterator it;
        for(int i=0;i<10;i++){
            scanf("%s",&mmp[i]);
            for(int j=0;j<10;j++){
                if(mmp[i][j]!='.'&&mmp[i][j]!='#'){
                    Node nodd;nodd.x=i;nodd.y=j;
                    m[mmp[i][j]]=nodd;
                }
            }
        }
        int flag=0;
        while(!m.empty()){
            flag=0;
            for(it=m.begin();it!=m.end();it++){
                if(bfs(it->first,it->second)){
                    flag=1;
                    ans[cnt++]=it->first;
                    m.erase(it->first);
                    break;
                }
            }
            if(!flag) break;
        }
        if(flag){
            for(int i=0;iprintf("%c",ans[i]);
            printf("\n");
        }else printf("My God!\n");
    }
}

你可能感兴趣的:(C/C++,搜索)