C. Mooyo Mooyo(dfs)

题目链接

题目大意:

给你n,k n为行数 列数为10,矩阵中有0~9的数字,0代表无,k为消去相同数字的最小个数。

若一个数的的上下左右有一个数与它相同,则它们是连通的。连通数若>=k,则可以将连通数字变为0;

消去后,由于重力非0数字下落。空位用0代替。下落后可能会产生新的连通块,继续消去,在模拟重力下落。

直至无连通块。输出模拟后的图。

题目分析:

求连通块用dfs ,再用vis数组标记相同数sum,若sum>=k,则可以消去,用0代替,若sum<k,则重置vis数组。

模拟重力过程我觉得比较难写,反正我写了很久。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200;
int vis[N][N],n,k,sum;
char a[N][N];
int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};
void dfs2(int x,int y,char s)
{
	vis[x][y]=1;
	for(int p=0;p<4;p++)
	{
		int nx=x+dx[p],ny=y+dy[p];
		if(nx<0||nx>=n||ny<0||ny>=10||a[nx][ny]!=s||vis[nx][ny])continue;
		sum++;
		dfs2(nx,ny,s);
	}
}
void clear()
{
	for(int i=0;i<n;i++){
		for(int j=0;j<10;j++){
			if(vis[i][j])
			{
				a[i][j]='0';
				vis[i][j]=0;
			}
		}
	}
}
int dfs1()
{
	int flag=0;
	for(int i=0;i<n;i++){
		for(int j=0;j<10;j++){
			if(a[i][j]!='0')
			{
				sum=1;
				dfs2(i,j,a[i][j]);
				if(sum>=k)
				{
					flag=1;
					clear();
					
				}
				else{
					memset(vis,0,sizeof(vis));
				}
			}
		}
	}
	if(flag)return 1;
	else return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{	scanf("%s",a[i]);
	}
	while(dfs1())
	{
        //模拟重力过程
		for(int i=0;i<10;i++)
        {
            int t=n;
            for(int j=n-1;j>=0;j--)
            {
                if(a[j][i]!='0')
                    a[--t][i]=a[j][i];
            }
            for(int j=t-1;j>=0;j--)
                a[j][i]='0';
        }
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<10;j++)
		{
			printf("%c",a[i][j]);
		}
		puts("");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_43490894/article/details/87532668