题目大意:
给你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("");
}
}