题目大意:有一个10*15的棋盘,棋盘上放满了3种颜色的棋子。每一次按照如下规则操作:选择连成一片棋子数最多的区域,如果有多个情况,选择起始位置最左边的,如果还是有多个情况的,选择最下面的。然后消去该片棋子。然后上方的棋子下落填补空缺,如果出现一列全为空的情况,则将右边一列的棋子整体左移。每次操作输出区域的消去区域起始位置,操作步数,消去区域的棋子数,棋子的颜色,得分。得分=(该步消去棋子数-2)^2。如果出现找不到棋子数大于2的区域,或者棋子全部消光的时候,游戏结束。最后输出总得分和剩余棋子数。
思路:模拟即可,dfs历遍。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
char chess[12][17],color_now,max_color;
bool have_visited[12][17];
int max_ball,max_row,max_column,cnt,score,step,num[3];
int start,end;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
map<char,int> mp;
void dfs(int row,int column)
{
int i;
have_visited[row][column]=true;
cnt++;
for (i=0;i<4;i++)
if (row+dx[i]<=10 && row+dx[i]>=1 && column+dy[i]<=15 && column+dy[i]>=1
&& have_visited[row+dx[i]][column+dy[i]]==false && chess[row+dx[i]][column+dy[i]]==color_now)
dfs(row+dx[i],column+dy[i]);
}
void dfs_modify(int row,int column)
{
int i;
have_visited[row][column]=true;
chess[row][column]='X';
for (i=0;i<4;i++)
if (row+dx[i]<=10 && row+dx[i]>=1 && column+dy[i]<=15 && column+dy[i]>=1
&& have_visited[row+dx[i]][column+dy[i]]==false && chess[row+dx[i]][column+dy[i]]==max_color)
dfs_modify(row+dx[i],column+dy[i]);
}
int main()
{
int test_cases,t,i,j,ii,jj;
mp.insert(pair<char,int> ('R',0));
mp.insert(pair<char,int> ('G',1));
mp.insert(pair<char,int> ('B',2));
scanf("%d",&test_cases);
for (t=1;t<=test_cases;t++)
{
memset(num,0,sizeof(num));
for (i=1;i<=10;i++)
for (j=1;j<=15;j++)
{
scanf(" %c",&chess[11-i][j]);
num[mp[chess[11-i][j]]]++;
}
printf("Game %d:\n\n",t);
step=1;
score=0;
while (1)
{
memset(have_visited,false,sizeof(have_visited));
max_ball=-1;
for (j=1;j<=15;j++)
for (i=1;i<=10;i++)
if (have_visited[i][j]==false && chess[i][j]!='X')
{
color_now=chess[i][j];
cnt=0;
dfs(i,j);
if (cnt>max_ball)
{
max_ball=cnt;
max_row=i;
max_column=j;
max_color=color_now;
}
}
if (max_ball<=1)
break;
printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n",
step++,max_row,max_column,max_ball,max_color,(max_ball-2)*(max_ball-2));
score+=(max_ball-2)*(max_ball-2);
num[mp[max_color]]-=max_ball;
memset(have_visited,false,sizeof(have_visited));
dfs_modify(max_row,max_column);
for (j=1;j<=15;j++)
{
while (1)
{
for (i=1;i<=10 && chess[i][j]!='X';i++);
if (i>10)
break;
else
start=i;
for (;i<=10 && chess[i][j]=='X';i++);
if (i>10)
break;
else
end=i-1;
for (i=start,ii=end+1;ii<=10;i++,ii++)
chess[i][j]=chess[ii][j];
for (;i<=10;i++)
chess[i][j]='X';
}
}
for (j=1;j<15;j++)
{
if (chess[1][j]=='X')
{
for (jj=j+1;chess[1][jj]=='X' && jj<=15;jj++);
if (jj>15)
break;
else
for (i=1;i<=10;i++)
{
chess[i][j]=chess[i][jj];
chess[i][jj]='X';
}
}
}
}
if (num[0]+num[1]+num[2]==0)
printf("Final score: %d, with 0 balls remaining.\n\n",score+1000);
else
printf("Final score: %d, with %d balls remaining.\n\n",score,num[0]+num[1]+num[2]);
}
return 0;
}

本文介绍了一个基于DFS算法的游戏棋盘消除得分系统,详细解释了如何通过模拟操作来计算得分并最终输出总得分和剩余棋子数。
4319

被折叠的 条评论
为什么被折叠?



