(HDU3295) An interesting mobile game- DFS+BFS

An interesting mobile game

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 607    Accepted Submission(s): 291


 

Problem Description

XQ,one of the three Sailormoon girls,is usually playing mobile games on the class.Her favorite mobile game is called “The Princess In The Wall”.Now she give you a problem about this game.
Can you solve it?The following picture show this problem better.


This game is played on a rectangular area.This area is divided into some equal square grid..There are N rows and M columns.For each grid,there may be a colored square block or nothing.
Each grid has a number.
“0” represents this grid have nothing.
“1” represents this grid have a red square block.
“2” represents this grid have a blue square block.
“3” represents this grid have a green square block.
“4” represents this grid have a yellow square block.

1. Each step,when you choose a grid have a colored square block, A group of this block and some connected blocks that are the same color would be removed from the board. no matter how many square blocks are in this group.
2. When a group of blocks is removed, the blocks above those removed ones fall down into the empty space. When an entire column of blocks is removed, all the columns to the right of that column shift to the left to fill the empty columns.

Now give you the number of the row and column and the data of each grid.You should calculate how many steps can make the entire rectangular area have no colored square blocks at least.

 

 

Input

There are multiple test cases. Each case starts with two positive integer N, M,(N, M <= 6)the size of rectangular area. Then n lines follow, each contains m positive integers X.(0<= X <= 4)It means this grid have a colored square block or nothing.

 

 

Output

Please output the minimum steps.

 

 

Sample Input

 

5 6 0 0 0 3 4 4 0 1 1 3 3 3 2 2 1 2 3 3 1 1 1 1 3 3 2 2 1 4 4 4

 

 

Sample Output

 

4

Hint

0 0 0 3 4 4 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 3 3 0 0 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 2 3 3 0 0 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 2 2 2 3 3 0 2 2 2 4 4 0 2 2 0 0 0 0 0 0 0 0 0 0 2 2 1 4 4 4 2 2 4 4 4 0 2 2 4 4 4 0 2 2 2 0 0 0 0 0 0 0 0 0

 

题目大意:

问消方块消完全部方块的最小次数。同数字可消。

分析:

同一个图,分别将不同颜色的块消掉,放入队列中,这是搜索树的属于同一层次的状态,然后如果都消完就将结果记下来,在所有消完的结果中找操作次数最少的那个就是答案。每次消完一次同颜色的块就判断一下是否进行左移下移操作,满足条件就进行相应的操作。

代码:

#include<iostream>
#include<queue>
using namespace std;
int N, M;
int maze[7][7];
struct Node {
	int m[7][7];
	int step;
	Node(int s = 0) {
		step = s;
	}
}a,temp;
int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
queue<Node> q;
bool vis[7][7];
//求同颜色的连通块
void dfs(int x, int y, int val) {
	for (int i = 0; i < 4; i++) {
		x += dir[i][0];
		y += dir[i][1];
		if (x >= 0 && x < N&&y >= 0 && y < M&&a.m[x][y] == val && !vis[x][y])
		{
			vis[x][y] = 1;
			a.m[x][y] = 0;
			dfs(x, y, val);
		}
		x -= dir[i][0];
		y -= dir[i][1];
	}
}
void bfs() {
	a.step = 0;
	while (!q.empty())q.pop();
	q.push(a);
	bool flag;

	while (!q.empty()) {
		a = q.front();
		q.pop();
		flag = 1;
		//判断是否消完,若最下面的为0则表明消完了。
		for (int i = 0; i < M; i++) {
			if (a.m[N - 1][i]) {
				flag = 0;
				break;
			}
		}
		//消完输出答案
		if (flag) {
			cout << a.step << endl;
			return;
		}
		a.step++;
		temp = a;
		memset(vis, false, sizeof(vis));
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				if (temp.m[i][j] && !vis[i][j])
				{
					vis[i][j] = 1;
					a.m[i][j] = 0;
					dfs(i, j, temp.m[i][j]);
					//左移操作
					for (int s = N - 1; s >= 0; s--)
					{
						for (int w = 0; w < M; w++)
						{
							if (!a.m[s][w])
							{
								for (int k = s - 1; k >= 0; k--) {
									if (a.m[k][w])
									{
										a.m[s][w] = a.m[k][w];
										a.m[k][w] = 0;
										break;
									}
								}
							}
						}
					}
					//下移操作
					for (int s = 0; s < M; s++) {
						if (a.m[N - 1][s] == 0)
						{
							for (int w = s; w < M - 1; w++)
							{
								for (int k = 0; k < N; k++)
								{
									a.m[k][w] = a.m[k][w + 1];
								}
							}
						}
					}
					q.push(a);
					a = temp;
				}
			}
		}
	}
}
int main() {
	while (cin >> N >> M) {
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < M; j++) {
				cin >> a.m[i][j];
			}
		}
		bfs();
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值