Mooyo Mooyo大模拟题解

题目传送门

链接:https://ac.nowcoder.com/acm/contest/7154/E
来源:牛客网

题目描述
由于手上(更确实的,蹄子上)有大把的空余时间,Farmer John的农场里的奶牛经常玩电子游戏消磨时光。她们最爱的游戏之一是基于一款人类中流行的电子游戏Puyo Puyo的奶牛版;名称当然叫做Mooyo Mooyo。
Mooyo Mooyo是在一块细长的棋盘上进行的游戏,高NN(1≤N≤100)格,宽10格。 这是一个N=6的棋盘的例子:

0000000000
0000000300
0054000300
1054502230
2211122220
1111111223
每个格子中或者是空的(用0表示),或者是九种颜色之一的干草捆(用字符1…9表示)。重力会使得干草捆下落,所以没有干草捆的下方是0。

如果两个格子水平或垂直方向直接相邻,并且为同一种非0颜色,那么这两个格子就属于同一个连通区域。任意时刻出现至少K个格子构成的连通区域,其中的干草捆就会全部消失,变为0。如果同时出现多个这样的连通区域,它们同时消失。随后,重力可能会导致干草捆向下落入某个变为0的格子。由此形成的新的布局中,又可能出现至少K个格子构成的连通区域。若如此,它们同样也会消失(如果又有多个这样的区域,则同时消失),然后重力又会使得剩下的方块下落,这一过程持续进行,直到不存在大小至少为K的连通区域为止。

给定一块Mooyo Mooyo棋盘的状态,输出这些过程发生之后最终的棋盘的图案。

输入描述:
输入的第一行包含N和K(1≤K≤10N)。以下N行给出了棋盘的初始状态。
输出描述:
输出N行,描述最终的棋盘状态。
示例1
输入
复制
6 3
0000000000
0000000300
0054000300
1054502230
2211122220
1111111223
输出
复制
0000000000
0000000000
0000000000
0000000000
1054000000
2254500000
说明
在上面的例子中,如果K=3,那么存在一个大小至少为K的颜色1的连通区域,同样有一个颜色2的连通区域。当它们同时被移除之后,棋盘暂时成为了这样:

0000000000
0000000300
0054000300
1054500030
2200000000
0000000003

然后,由于重力效果,干草捆下落形成这样的布局:

0000000000
0000000000
0000000000
0000000000
1054000300
2254500333

再一次地,出现了一个大小至少为K的连通区域(颜色3)。移除这个区域就得到了最终的棋盘布局:

0000000000
0000000000
0000000000
0000000000
1054000000
2254500000

首先 就是我们要明白K,其实就是找连通块的点需要>=k,然后就是直接DFS找连通块,然后判断与K 的大小,大于等于他那么就可以把这一块的全部变成0,注意 ,每次都要全图跑完然后处理成0,然后才开始下落,如果只是单独跑一个连通块就下,那么有些不可以消除的就有可能消除,所有 每次跑完所有的连通块然后再下落,下落的时候又是一个细节,需要我们从下面处理上来,因为下面的先掉下去,上面的才随后下降,本题数据很小,所以暴搜可以。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include <assert.h> //设定插入点
#include <ctype.h> //字符处理
#include <errno.h> //定义错误码
#include <float.h> //浮点数处理
//#include <cfstream> //文件输入/输出
//#include <iomanip.h> //参数化输入/输出
//#include <iostream.h> //数据流输入/输出
#include <limits.h> //定义各种数据类型最值常量
#include <locale.h> //定义本地化函数
#include <math.h> //定义数学函数
#include <stdio.h> //定义输入/输出函数
#include <stdlib.h> //定义杂项函数及内存分配函数#include <string.h> //字符串处理
//#include <strstrea.h> //基于数组的输入/输出
#include <time.h> //定义关于时间的函数#include <wchar.h> //宽字符处理及输入/输出
#include <wctype.h> //宽字符分类//标准 C++ (同上的不再注释)
#include <algorithm> //STL 通用算法
#include <bitset> //STL 位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类#include <cstdio>#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL 双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL 定义运算函数(代替运算符)
#include <limits>
#include <list> //STL 线性列表容器#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持#include <iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL 队列容器
#include <set> //STL 集合容器#include <sstream> //基于字符串的流
#include <stack> //STL 堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL 通用模板类
#include <vector> //STL 动态数组容器
#include <cwchar>
#include <cwctype>//C99 增加
#include <complex.h> //复数处理
#include <fenv.h> //浮点环境
#include <inttypes.h> //整数格式转换
#include <stdbool.h> //布尔环境
#include <stdint.h> //整型环境
#include <tgmath.h> //通用类型数学宏
#include <map>
#define ll long long
#define ull unsigned long long
#define fio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mse(a,b) memset(a,b,sizeof a)
#define pb push_back
using namespace std;
const int maxx=1e6+100;
const int mod=1e9+7;
const long double PI = 3.14159265358979323846;
inline int read()
{ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)) { x=x*10+ch-48;  ch=getchar();  } return x*f;
}
char ans[200][200];
int vis[200][200];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int n,k;
int sum;
void dfs(int x,int y,char a)
{
    vis[x][y]=1;
    for(int i=0;i<4;i++){
        int ax=x+dx[i];
        int ay=y+dy[i];
        if(ans[ax][ay]==a && vis[ax][ay]==0)
        {
            sum++;
            dfs(ax,ay,a);
        }
    }
}
void update(){
    for(int i=n-1;i>=0;i--)
    {
        for(int j=0;j<10;j++)
        {
            int p=i;
            if(ans[i][j]!=0)
            {
               // cout<<ans[p+1][j]<<endl;
                while(ans[p+1][j]=='0'&&p+1<n){
                    p++;
                   // cout<<p<<endl;
                }
                if(p!=i)
                {
                    ans[p][j]=ans[i][j];
                    ans[i][j]='0';
                }
                
            }
        }
    }
}
signed main(){
    cin.tie(0);std::ios::sync_with_stdio(false);
   cin>>n>>k;
   for(int i=0;i<n;i++)
   cin>>ans[i];
    int flag=1;
    while(flag)
    {
        flag=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<10;j++){
                if(ans[i][j]!='0')
                {
                    mse(vis,0);
                    sum=1;
                    dfs(i,j,ans[i][j]);
                    if(sum>=k)
                    {
                        for(int p=0;p<n;p++)
                        for(int q=0;q<10;q++){
                            if(vis[p][q]) ans[p][q]='0';
                        }
                        flag=1;
                    }
                }
              
            }
        }
        if(flag)
               update();
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<10;j++)
        cout<<ans[i][j];
        cout<<endl;
    }
 // system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值