POJ 1027:The Same Game 较(chao)为(ji)复(ma)杂(fan)的模拟

The Same Game
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5168   Accepted: 1944

Description

The game named "Same" is a single person game played on a 10 \Theta 15 board. Each square contains a ball colored red (R), green (G), or blue (B). Two balls belong to the same cluster if they have the same color, and one can be reached from another by following balls of the same color in the four directions up, down, left, and right. At each step of the game, the player chooses a ball whose cluster has at least two balls and removes all balls in the cluster from the board. Then, the board is "compressed" in two steps: 
1. Shift the remaining balls in each column down to fill the empty spaces. The order of the balls in each column is preserved. 
2. If a column becomes empty, shift the remaining columns to the left as far as possible. The order of the columns is preserved. 
For example, choosing the ball at the bottom left corner in the sub-board below causes: 
 
The objective of the game is to remove every ball from the board, and the game is over when every ball is removed or when every cluster has only one ball. The scoring of each game is as follows. The player starts with a score of 0. When a cluster of m balls is removed, the player's score increases by (m-2)^2 . A bonus of 1000 is given if every ball is removed at the end of the game. 
You suspect that a good strategy might be to choose the ball that gives the largest possible cluster at each step, and you want to test this strategy by writing a program to simulate games played using this strategy. If there are two or more balls to choose from, the program should choose the leftmost ball giving the largest cluster. If there is still a tie, it should choose the bottommost ball of these leftmost balls.

Input

You will be given a number of games in the input. The first line of input contains a positive integer giving the number of games to follow. The initial arrangement of the balls of each game is given one row at a time, from top to bottom. Each row contains 15 characters, each of which is one of "R", "G", or "B", specifying the colors of the balls in the row from left to right. A blank line precedes each game.

Output

For each game, print the game number, followed by a new line, followed by information about each move, followed by the final score. Each move should be printed in the format: 
Move x at (r,c): removed b balls of color C, got s points. 
where x is the move number, r and c are the row number and column number of the chosen ball, respectively. The rows are numbered from 1 to 10 from the bottom, and columns are numbered from 1 to 15 from the left. b is the number of balls in the cluster removed. C is one of "R", "G", or "B", indicating the color of the balls removed. s is the score for this move. The score does not include the 1000 point bonus if all the balls are removed after the move. 
The final score should be reported as follows: 
Final score: s, with b balls remaining. 
Insert a blank line between the output of each game. Use the plural forms "balls" and "points" even if the corresponding value is 1.

Sample Input

3 
RGGBBGGRBRRGGBG 
RBGRBGRBGRBGRBG
RRRRGBBBRGGRBBB
GGRGBGGBRRGGGBG
GBGGRRRRRBGGRRR
BBBBBBBBBBBBBBB
BBBBBBBBBBBBBBB
RRRRRRRRRRRRRRR
RRRRRRGGGGRRRRR
GGGGGGGGGGGGGGG

RRRRRRRRRRRRRRR
RRRRRRRRRRRRRRR
GGGGGGGGGGGGGGG
GGGGGGGGGGGGGGG
BBBBBBBBBBBBBBB
BBBBBBBBBBBBBBB
RRRRRRRRRRRRRRR
RRRRRRRRRRRRRRR 
GGGGGGGGGGGGGGG
GGGGGGGGGGGGGGG

RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG

Sample Output

Game 1: 

Move 1 at (4,1): removed 32 balls of color B, got 900 points. 
Move 2 at (2,1): removed 39 balls of color R, got 1369 points. 
Move 3 at (1,1): removed 37 balls of color G, got 1225 points. 
Move 4 at (3,4): removed 11 balls of color B, got 81 points. 
Move 5 at (1,1): removed 8 balls of color R, got 36 points. 
Move 6 at (2,1): removed 6 balls of color G, got 16 points. 
Move 7 at (1,6): removed 6 balls of color B, got 16 points. 
Move 8 at (1,2): removed 5 balls of color R, got 9 points. 
Move 9 at (1,2): removed 5 balls of color G, got 9 points. 
Final score: 3661, with 1 balls remaining. 

Game 2: 

Move 1 at (1,1): removed 30 balls of color G, got 784 points. 
Move 2 at (1,1): removed 30 balls of color R, got 784 points. 
Move 3 at (1,1): removed 30 balls of color B, got 784 points. 
Move 4 at (1,1): removed 30 balls of color G, got 784 points. 
Move 5 at (1,1): removed 30 balls of color R, got 784 points. 
Final score: 4920, with 0 balls remaining. 

Game 3: 

Final score: 0, with 150 balls remaining. 

题意是给了在一个10*15的棋盘上有一堆球,然后这些球通过相连形成一个一个的簇,每一轮删除球数量最多的那个簇,然后球会自动的往下落。如果其中某一列空了,那么球会整列的往左边移动,而不是像上下那样自由移动。每一轮消除小球会有相应的分数,问最终剩下的球与分数。

其实这种题没什么难的,就是细心一些就能把它解开,POJ把这个题弄到了“较为复杂的模拟题”里面,真的是麻烦,理解题意,然后考虑情况啥的之类的,弱菜的自己写了一个晚上加一个上午。。。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int cluster_num;
char value;
char val[20][20];
int vis[20][20];
int num[20][20];
int col_val[20][20];
int row_val[20][20];

void dfs_delete(int x, int y)
{
	val[x][y] = 0;
	vis[x][y] = 1;

	if (val[x - 1][y] == value&&vis[x - 1][y] == 0)
	{
		dfs_delete(x - 1, y);
	}

	if (val[x + 1][y] == value&&vis[x + 1][y] == 0)
	{
		dfs_delete(x + 1, y);
	}

	if (val[x][y - 1] == value&&vis[x][y - 1] == 0)
	{
		dfs_delete(x, y - 1);
	}

	if (val[x][y + 1] == value&&vis[x][y + 1] == 0)
	{
		dfs_delete(x, y + 1);
	}
}

void dfs(int x, int y)
{
	cluster_num++;
	vis[x][y] = 1;

	if (val[x - 1][y] == value&&vis[x - 1][y] == 0)
	{
		dfs(x - 1, y);
	}

	if (val[x + 1][y] == value&&vis[x + 1][y] == 0)
	{
		dfs(x + 1, y);
	}

	if (val[x][y - 1] == value&&vis[x][y - 1] == 0)
	{
		dfs(x, y - 1);
	}

	if (val[x][y + 1] == value&&vis[x][y + 1] == 0)
	{
		dfs(x, y + 1);
	}
}

int main()
{
	//freopen("i.txt","r",stdin);
	//freopen("o.txt","w",stdout);
	int test, itest, i, j, sum, inum, remove_num, row_num, col_num;
	cin >> test;

	for (itest = 1; itest <= test; itest++)
	{
		cout << "Game " << itest << ":" << endl << endl;

		for (i = 10; i >= 1; i--)
		{
			cin >> val[i] + 1;
		}

		sum = 0;
		remove_num = 0;
		inum = 1;
		row_num = 10;
		col_num = 15;
		while (true)
		{
			memset(vis, 0, sizeof(vis));
			memset(num, 0, sizeof(num));

			for (i = 1; i <= 15; i++)
			{
				for (j = 1; j <= 10; j++)
				{
					if (val[j][i] == 0)continue;
					if (j == 1 && i == 6)
					{
						j++;
						j--;
					}
					if (vis[j][i] == 0)//第j行第i列
					{
						cluster_num = 0;
						value = val[j][i];

						dfs(j, i);

						num[j][i] = cluster_num;
					}
				}
			}

			int maxn;
			int x, y;

			maxn = 1;
			for (i = 1; i <= 15; i++)
			{
				for (j = 1; j <= 10; j++)
				{
					if (num[j][i] > maxn)
					{
						maxn = num[j][i];
						x = j;
						y = i;
					}
				}
			}

			if (maxn == 1)
				break;
			else
			{
				cout << "Move " << inum << " at (" << x << "," << y << "): removed " << maxn << " balls of color " << val[x][y] << ", got " << (maxn - 2)*(maxn - 2) << " points. " << endl;

				sum += (maxn - 2)*(maxn - 2);
				remove_num += maxn;

				memset(vis, 0, sizeof(vis));
				value = val[x][y];
				dfs_delete(x, y);
			}
		
			memset(col_val, 0, sizeof(col_val));
			
			for (j = 1; j <= 15; j++)//横着移动球
			{
				int c_n = 0;
				for (i = 1; i <= 10; i++)
				{
					if (val[i][j] == 0)
						continue;
					else
					{
						col_val[c_n++][j] = val[i][j];
					}
				}

				c_n = 0;
				for (i = 1; i <= 10; i++)
				{
					val[i][j] = col_val[c_n++][j];
				}
			}

			for (j = 1; j <= col_num; j++)//竖着移动球
			{
				for (i = 10; i >= 1; i--)
				{
					if (val[i][j] == 0)
						continue;
					else
						break;
				}
				if (i == 0)
				{
					int k, p;
					for (k = j + 1; k <= col_num; k++)
					{
						for (p = 10; p >= 1; p--)
						{
							val[p][k - 1] = val[p][k];
						}
					}
					for (i = 10; i >= 1; i--)
					{
						val[i][col_num] = 0;
					}
					j--;
					col_num--;
				}
			}
			
			inum++;
		}

		if (remove_num == 150)
		{
			sum += 1000;
		}
		cout << "Final score: " << sum << ", with " << 150 - remove_num << " balls remaining." << endl << endl;
	}

	//system("pause");
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-10-25 13:10  光速小子  阅读(196)  评论(0编辑  收藏  举报

导航