-
[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;
}