解析:将所有的cell按高度从大到小排序,然后每次放入值相同的cell,用并查集维护集合和集合大小,并判断是否满足条件即可。找到后搜索标记所有的位置。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
long long mp[1005][1005];
struct node
{
long long v;
int x,y;
int id;
}pt[1005*1005];
int f[1005*1005];
int cnt[1005*1005];
struct node1
{
int u,v;
int nex;
}edge[3*1005*1005];
int ct;
int head[1005*1005];
void add(int u,int v)
{
edge[ct].u=u;
edge[ct].v=v;
edge[ct].nex=head[u];
head[u]=ct++;
}
bool cmp(node a,node b)
{
return a.v>b.v;
}
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int gf(int x)
{
if(x!=f[x])
{
f[x]=gf(f[x]);
}
return f[x];
}
struct node2
{
int x,y;
node2(int xx,int yy)
{
x=xx;y=yy;
}
};
int n,m;
void bfs(int s,int num,long long cv)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]>=cv)
mp[i][j]=-1;
}
}
queue<node2> q;
int x=s/m;
int y=s%m;
node2 sta(x,y);
q.push(sta);
while(!q.empty()&&num>0)
{
num--;
node2 cur=q.front();
q.pop();
int x=cur.x;
int y=cur.y;
mp[x][y]=cv;
for(int i=0;i<4;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m)
{
if(mp[xx][yy]==-1)
{
node2 nex(xx,yy);
q.push(nex);
mp[xx][yy]--;
}
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]!=cv)
mp[i][j]=0;
}
}
return ;
}
int main()
{
long long k;
while(~scanf("%d%d%lld",&n,&m,&k))
{
for(int i=0;i<1001*1001;i++)
{
f[i]=i;
cnt[i]=1;
head[i]=-1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%lld",&mp[i][j]);
pt[i*m+j].x=i;
pt[i*m+j].y=j;
pt[i*m+j].id=i*m+j;
//printf("%d\n",pt[i*m+j].id);
pt[i*m+j].v=mp[i][j];
}
}
sort(pt,pt+n*m,cmp);
for(int i=0;i<n*m;i++)
{
//printf("%d:%d:%d\n",pt[i].x,pt[i].y,pt[i].v);
int cid=pt[i].id;
int cx=pt[i].x;
int cy=pt[i].y;
long long cv=pt[i].v;
//printf("%d\n",cnt[cid]);
int fy=gf(cid);
for(int j=0;j<4;j++)
{
int xx=cx+dir[j][0];
int yy=cy+dir[j][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m)
{
if(mp[xx][yy]>=cv)
{
int fx=gf(xx*m+yy);
if(fx!=fy)
{
f[fx]=fy;
cnt[fy]+=cnt[fx];
//add(fy,fx);
}
}
}
}
//printf("%lld %d %d %d\n",cv,cnt[cid],cx,cy);
if(k%cv==0)
{
long long ned=k/cv;
if(cnt[fy]>=ned)
{
bfs(cid,ned,cv);
printf("YES\n");
for(int kk=0;kk<n;kk++)
{
for(int p=0;p<m;p++)
{
printf("%d ",mp[kk][p]);
}
printf("\n");
}
return 0;
}
}
}
printf("NO\n");
}
}