NOJ 1009连连看

  • [1009] 连连看

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 大家都知道一个曾经风靡一时的游戏:连连看。 XadillaX在做连连看的时候不专心,做做就去玩别的去了,但他想早点完成这个小游戏,于是他找到你来帮他完成连连看的一段核心代码。 首先会给出一副连连看的分布图形,然后会给你各种鼠标点击操作(鼠标点击的坐标),你的工作就是算出最后还剩下几个方块。 鼠标操作之后的判断是这样的:在没有记录任何图形的情况下,第一下点击会记录当前点击的图形,第二下以及之后的每次点击都会记录点击的图形,并且与之前的图形对比,如果可消就消掉两块,如果不可消就将之前之前点击的图形取消记录(但不取消记录当前点击的图形)。可消的概念就是能在两次拐角内能连接起来,并且两个图形是相同的。若点击的是空块,则不做任何操作。

  • 输入
  • 第一行一个正整数T(0 < T <= 10),表示数据组数。
    接下来T组数据,每组数据的第一行是两个正整数n和m(2 <= m, n <= 100),表示连连看分布图的高和宽(每个图形占一个单位高和宽)。
    接下来n行表示图形的分布,由大写'A'~'Z'以及'0'组成,其中大写字母代表一个图形(相同字母的表示图形相同),'0'表示这个地方为空。
    接下来一行为一个正整数Q(1 <= Q <= 100),代表鼠标操作次数。
    最后Q行,每行有两个正整数,代表鼠标点击的坐标Xi, Yi(0 <= Xi, Yi, < 100)。
  • 输出
  • 对于每组,输出个正整数,代表本组数据最终会剩下几个图形。一组数据占一行。
  • 样例输入
  • 1
    3 3
    QZZ
    I0Q
    AAI
    6
    0 0
    2 1
    2 0
    1 0
    0 0
    2 1
    
  • 样例输出
  • 4
  • 思路:哈哈哈哈,模拟呀~~
  • 用BFS搜就行啦,记录转弯次数,超过2次的直接GG掉
  • 然后搜之前在外围补一圈0,别问为什么。
  • #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    int n,m,k,lx,ly,nx,ny,flag;
    int f[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
    char mp[105][105];
    bool vis[105][105];
    bool jug(int x,int y,int tx,int ty)
    {
        if(x<0||x>n+1||y<0||y>m+1)return false;
        if(mp[x][y]=='0')
        return true;
        if(x==tx&&y==ty)
        return true;
        return false;
    }
    struct node
    {
        int x,y,turn,f;
    };
    int bfs(int sx,int sy,int tx,int ty)
    {
        node s,t;
        queue<node> q;
        s.x=sx,s.y=sy,s.turn=0,s.f=-1;
        q.push(s);
        while(!q.empty())
        {
            s=q.front();q.pop();//printf("%d %d %d\n",s.x,s.y,s.turn);
            if(s.x==tx&&s.y==ty&&s.turn<=3)
            {   //printf("asdasd\n");
                mp[sx][sy]='0';mp[tx][ty]='0';return 1;
            }
            for(int i=0;i<4;i++)
            {
                t.x=s.x+f[i][0],t.y=s.y+f[i][1];
                if(jug(t.x,t.y,tx,ty)&&!vis[t.x][t.y])
                {
                    vis[t.x][t.y]=1;
                    if(s.f!=i)t.turn=s.turn+1;
                    else t.turn=s.turn;
                    t.f=i;
                    if(t.turn<=3)
                    q.push(t);
                }
            }
        }
        return 0;
    }
    int main()
    {
        int T,ans;
        scanf("%d",&T);
        while(T--)
        {   flag=0;ans=0;
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;i++)
                scanf("%s",mp[i]+1);
            for(int i=0;i<=n+1;i++)
            {
                for(int j=0;j<=m+1;j++)
                {
                    if(i==0||i==n+1)mp[i][j]='0';
                    if(j==0||j==m+1)mp[i][j]='0';
                }
            }
            scanf("%d",&k);
            lx=-1,ly=-1;
            for(int i=1;i<=k;i++)
            {
               scanf("%d %d",&ny,&nx);
               ny++,nx++;
               if(lx!=-1&&ly!=-1)
               {
                   if(mp[nx][ny]==mp[lx][ly]&&mp[nx][ny]!='0')
                   memset(vis,0,sizeof(vis)),flag=bfs(nx,ny,lx,ly);
               }//printf("%d %d %d %d %d\n",flag,lx,ly,nx,ny);
               if(mp[nx][ny]!='0'&&!flag)
               lx=nx,ly=ny;
               if(flag)
               lx=-1,ly=-1,flag=0;
            }
         //   for(int i=1;i<=n;i++)
          //      printf("%s\n",mp[i]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                if(mp[i][j]!='0')ans++;
            printf("%d\n",ans);
        }
        return 0;
    }

     

posted @ 2016-08-29 12:59  发光的微小微  阅读(137)  评论(0编辑  收藏  举报