POJ-1027 (模拟题)

模拟题

设置四个函数

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值