现在的位置: 首页 > 综合 > 正文

NOJ1009——连连看

2019年02月16日 ⁄ 综合 ⁄ 共 1997字 ⁄ 字号 评论关闭
文章目录
  • [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
    
  • 提示
  • 第一次选中了Q,第二次选中了Q,但是因为不能两次拐角内消除,所以第一次的Q取消选中状态,然后第三次选中Z,则第二次的Q取消选
    中,接着选中Z,两者消掉。接下去选中Q、Q,消除。最后剩下两个I和两个A。
  • 来源
  • XadillaX
  • 操作

深搜+判断

#include<map>
#include<set>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

char mat[105][105];
bool vis[105][105];
int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
int n, m, lx, ly;
bool F;

bool is_legal(int x, int y)
{
    if(x < 0 || x >= m || y < 0 || y >= n)
        return false;
    return true;
}

void dfs(int x, int y, int dirs, int cnt)
{
    if(F)
        return ;
    if(cnt > 2)
        return;
    if(x == lx && y == ly)
    {
        F = true;
        return;
    }
    for(int i = 0; i < 4; i++)
    {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if( !is_legal(xx, yy) )
            continue;
        if((xx != lx || yy != ly) && mat[xx][yy] != '0')
            continue;
        if(vis[xx][yy])
            continue;
        vis[xx][yy] = 1;
        int t = cnt;
        if((dirs >= 0 && dirs <= 1) && (i >= 2 && i <= 3))
            t++;
        if((i >= 0 && i <= 1) && (dirs >= 2 && dirs <= 3))
            t++;
        dfs(xx, yy, i, t);
        vis[xx][yy] = 0;
    }
}

int main()
{
    int t;
    int ans, all, q, x, y;
    bool flag;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);
        all = 0;
        flag = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%s", mat[i]);
            for(int j = 0; j < m; j++)
            {
                if(mat[i][j] != '0')
                    all++;
            }
        }
        scanf("%d", &q);
        while(q--)
        {
            scanf("%d%d", &y, &x);
            if(flag == 0)
            {
                flag = 1;
                lx = x;
                ly = y;
            }
            else
            {
                if(mat[x][y] != mat[lx][ly])
                {
                    lx = x;
                    ly = y;
                    continue;
                }
                memset( vis, 0, sizeof(vis) );
                vis[x][y] = 1;
                F = false;
                dfs(x, y, -1, 0);
                if(F == true)
                {
                    flag = 0;
                    all -= 2;
                    mat[lx][ly] = '0';
                    mat[x][y] = '0';
                }
                else
                {
                    lx = x;
                    ly = y;
                }
            }
        }
        printf("%d\n", all);
    }
    return 0;
}

抱歉!评论已关闭.