解析:将所有的cell按高度从大到小排序,然后每次放入值相同的cell,用并查集维护集合和集合大小,并判断是否满足条件即可。找到后搜索标记所有的位置。
[code]:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define lowbit(i) (i&-i)
using namespace std;
typedef long long LL;
struct Node{
int id,val;
bool operator < (const Node &z) const{
return val > z.val;
}
}C[1005*1005];
int n,m,a[1005][1005],b[1005][1005];
LL total,num[1005*1005];
int par[1005*1005],vis[1005*1005];
int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};
void init(){
for(int i = 0;i < n*m;i++){
par[i] = i;
num[i] = 1;
}
}
int find(int x){
return par[x]==x?x:par[x]=find(par[x]);
}
void unite(int x,int y){
x = find(x),y = find(y);
if(x == y) return;
par[y] = x;
num[x] += num[y];
}
LL check(int x,int y){
int k,nx,ny;
for(k = 0;k < 4;k++){
nx = x +dx[k];
ny = y +dy[k];
if(nx<0||nx>=n||ny<0||ny>=m||!vis[nx*m+ny]) continue;
unite(x*m+y,nx*m+ny);
}
return num[find(x*m+y)];
}
void dfs(int x,int y,int val){
if(vis[x*m+y]==0) return;
if(total > 0){
b[x][y] = val;
total -= val;
}
vis[x*m+y] = 0;
int k,nx,ny;
for(k = 0;k < 4;k++){
nx = x +dx[k];
ny = y +dy[k];
if(nx<0||nx>=n||ny<0||ny>=m) continue;
dfs(nx,ny,val);
}
}
int main(){
int i,j;
scanf("%d%d%I64d",&n,&m,&total);
init();
for(i = 0;i < n;i++){
for(j = 0;j < m;j++){
scanf("%d",&a[i][j]);
C[i*m+j].id = i*m+j;
C[i*m+j].val = a[i][j];
}
}
sort(C,C+n*m);
LL tmp,cnt;bool flag,ok;
for(i = 0;i < n*m;i = j){
tmp = total/C[i].val;
flag = total%C[i].val==0;
ok = 0;
for(j = i;j < n*m&&C[j].val==C[i].val;j++){
vis[C[j].id] = 1;
cnt = check(C[j].id/m,C[j].id%m);
if(flag&&cnt>=tmp){
ok = 1;
break;
}
}
if(ok){
puts("YES");
dfs(C[j].id/m,C[j].id%m,C[j].val);
int ii,jj;
for(ii = 0;ii < n;ii++){
for(jj = 0;jj < m;jj++){
printf("%d ",b[ii][jj]);
}
putchar('\n');
}
return 0;
}
}
puts("NO");
return 0;
}