模拟题
设置四个函数
void SearchMaxArea(void);//搜索当前地图的最大区域
int BFS(int i,int j);//同色区域搜索,返回该区域的大小
void Delete(void);//删除最大区域
void Update(void);//刷新地图
备注:这个题刚开始做的时候以为和消消乐游戏一样,以为是让求得分最大的那种情况,导致刚开始没有头绪解。后来才知道这道题题目中已经告诉我了,每次步骤消去最大的那个集群即可,按照它这种规则去写就行了。是我一开始没审好题,理解错了题意。
所以以后读懂题意,知道题目让我干什么是很关键的一步!!
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
char ma[10][16];//输入地图坐标
bool visit[10][16];//标记数组
int Maxsize=-1;//记录每次消去的最大个数
char Maxcolor;//颜色
int MaxR,MaxC;//行坐标 列坐标
void SearchMaxArea(void);//搜索当前地图的最大区域
int BFS(int i,int j);//同色区域搜索,返回该区域的大小
void Delete(void);//删除最大区域
void Update(void);//刷新地图
int main()
{
// freopen("in.txt","r",stdin);
std::ios::sync_with_stdio(false);
int T;
cin>>T;
for(int t=1;t<=T;t++)
{
cout<<"Game "<<t<<":"<<endl<<endl;
for(int i=9;i>=0;i--)
// for(int j=0;j<15;j++)
cin>>ma[i];
int step=0;//步骤
int remainBalls=150;//剩余字符数
int SumScore=0;//总点数
while(true)
{
Maxsize=-1;
SearchMaxArea();
if(Maxsize==0||Maxsize==1)
break;
Delete();
Update();
int score=(Maxsize-2)*(Maxsize-2);
cout<<"Move "<<++step<<" at ("<<MaxR+1<<','<<MaxC+1<<"): ";
cout<<"removed "<<Maxsize<<" balls of color "<<Maxcolor<<", got "<<score<<" points."<<endl;
remainBalls-=Maxsize;
SumScore+=score;
}
if(remainBalls==0)
SumScore+=1000;
cout<<"Final score: "<<SumScore<<", with "<<remainBalls<<" balls remaining."<<endl<<endl;
}
return 0;
}
void SearchMaxArea(void)
{
memset(visit,false,sizeof(visit));
Maxsize=0;
for(int j=0;j<15;j++)
for(int i=0;i<10;i++)
{
int Size=0;
if(!visit[i][j]&&ma[i][j])
{
Size=BFS(i,j);
if(Size>Maxsize)
{
Maxsize=Size;
MaxR=i;
MaxC=j;
}
}
}
return;
}
int BFS(int i,int j)
{
struct node
{
int x,y;
}que[151];//记录150个字符的坐标
int head ,tail;//从 头一个点到尾点一共搜到的下标
head=0;
tail=0;
que[head].x=i;
que[tail].y=j;
tail++;
visit[i][j]=true;
int Size=0;
char color=ma[i][j];
while(head<tail)//搜索到的相同点的个数
{
int x=que[head].x;
int y=que[head].y;
head++;
Size++;
if(x+1<10&&!visit[x+1][y]&&ma[x+1][y]==color)//上
{
visit[x+1][y]=true;
que[tail].x=x+1;
que[tail].y=y;
tail++;
}
if(x-1>=0&&!visit[x-1][y]&&ma[x-1][y]==color)//下
{
visit[x-1][y]=true;
que[tail].x=x-1;
que[tail].y=y;
tail++;
}
if(y-1>=0&&!visit[x][y-1]&&ma[x][y-1]==color)//左
{
visit[x][y-1]=true;
que[tail].x=x;
que[tail].y=y-1;
tail++;
}
if(y+1<15&&!visit[x][y+1]&&ma[x][y+1]==color)//右
{
visit[x][y+1]=true;
que[tail].x=x;
que[tail].y=y+1;
tail++;
}
}
return Size;
}
void Delete(void)
{
struct node
{
int x,y;
}que[151];
int head=0,tail=0;
que[head].x=MaxR;
que[tail].y=MaxC;
tail++;
Maxcolor=ma[MaxR][MaxC];
ma[MaxR][MaxC]=0;
while(head<tail)
{
int x=que[head].x;
int y=que[head].y;
head++;
ma[x][y]=0;
if(x+1<10&&ma[x+1][y]==Maxcolor)//上
{
ma[x+1][y]=0;
que[tail].x=x+1;
que[tail].y=y;
tail++;
}
if(x-1>=0&&ma[x-1][y]==Maxcolor)//下
{
ma[x-1][y]=0;
que[tail].x=x-1;
que[tail].y=y;
tail++;
}
if(y-1>=0&&ma[x][y-1]==Maxcolor)//左
{
ma[x][y-1]=0;
que[tail].x=x;
que[tail].y=y-1;
tail++;
}
if(y+1<15&&ma[x][y+1]==Maxcolor)//右
{
ma[x][y+1]=0;
que[tail].x=x;
que[tail].y=y+1;
tail++;
}
}
return;
}
void Update(void)
{
bool Empty[15]={false};//标记全列为空的那一列
int i,j;
/*处理从上到下的移动*/
for(j=0;j<15;j++)
{
bool flag=false;//标记第j列是否全列为空
int pi=-1;
for(i=0;i<10;i++)
{
if(ma[i][j])//该元素没有被标记0
{
flag=true;//说明该j列全列不为空
if(pi!=-1)//如果pi指向元素为0的行下标时,执行下面的语句,实现替换
{
ma[pi][j]=ma[i][j];
ma[i][j]=0;
i=pi;//下次从pi行坐标开始找ma数组为0的元素
pi=-1;//让pi重新为-1,当找到下一个被标记为0的元素再让pi指向那个元素的行下标
}
}
else//如果该元素被标记为0,说明该元素要被清空删除
{
pi=i;//用pi记录被删除元素的行号
while(i+1<10&&!ma[i+1][j])//继续找被标记为0的元素,一直找到没被标记为0的元素为止
i++;
}
}
if(!flag)//如果第j列flag一直为false时,说明j列全列为空
Empty[j]=true;//第j列为空
}
/*处理从右往左的移动*/
int k=-1;
for(j=0;j<15;j++)
{
if(!Empty[j])//如果该列不为空
{
if(k!=-1)//如果k指向列为空的那一列时,执行下面的语句,实现让全列右移的功能
{
for(int x=0;x<10;x++)
{
ma[x][k]=ma[x][j];
ma[x][j]=0;
}
Empty[j]=true;//此时第j列边为空了
j=k;
k=-1;
}
}
else//如果该列为空
{
k=j;//让k指向空的那列
while(j+1<15&&Empty[j+1])//判断下一列是否也为空,如果为空就让j++,一直找到不为空的那列
j++;
}
}
return;
}
网上的题解,原作者链接:https://blog.csdn.net/lyy289065406/article/details/6648655