题意
给你一个n*m的矩阵,然后给你一个k
这个矩阵里面的数,只能减小,不能增加。
然后你要是的矩阵最后只剩下一个连通块,且连通块里面有一个位置的数没有改变。
连通块的权值和恰好等于k
让你输出一个解。
题解:
把所有数,从大到小排序,然后用并查集去维护
只要当前这个连通块的大小大于等于k/a[i][j]就好了
然后输出的时候用bfs去输出,去维护这个连通块的大小
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-12
#define maxn 1000100
#define MOD 1000000007
struct node
{
int val;
int x,y;
bool operator<(const node &a)const
{
return val > a.val;
}
} cnt[maxn];
int n,m;
int a[1010][1010],b[1010][1010],num[maxn];
int fa[maxn],vis[1010][1010];
int mx[4] = {0,0,1,-1};
int my[4] = {1,-1,0,0};
long long k;
int Find(int x)
{
return x == fa[x]?x:fa[x] = Find(fa[x]);
}
void Union(int x,int y)
{
int px = Find(x);
int py = Find(y);
if(px != py)
{
fa[px] = py;
num[py] += num[px];
}
}
void bfs(int xx,int yy,int len)
{
queue<pair<int,int> > q;
q.push(make_pair(xx,yy));
b[xx][yy] = a[xx][yy];
int Num = 1;
if(Num == len)
return;
vis[xx][yy] = 1;
while(!q.empty())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++)
{
int px = x + mx[i];
int py = y + my[i];
if(px < 0 || px >= n || py < 0 || py >= m || vis[px][py])
continue;
vis[px][py] = 1;
if(a[px][py] >= a[xx][yy])
{
b[px][py] = a[xx][yy];
q.push(make_pair(px,py));
if(++Num == len)
return;
//printf("%lld %lld\n",Num,len);
}
}
}
}
int main()
{
int t;
while(scanf("%d%d%lld",&n,&m,&k) != EOF)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
scanf("%d",&a[i][j]);
cnt[i*m+j].val = a[i][j];
cnt[i*m+j].x = i;
cnt[i*m+j].y = j;
}
sort(cnt,cnt+n*m);
for(int i = 0; i < n*m; i++)
{
fa[i] = i;
num[i] = 1;
}
int flag = 0;
for(int i = 0; i < n*m; i++)
{
int val = cnt[i].val;
if(!val)
break;
int x = cnt[i].x;
int y = cnt[i].y;
for(int j = 0; j < 4; j++)
{
int px = x + mx[j];
int py = y + my[j];
if(px < 0 || px >= n || py < 0 || py >= m)
continue;
if(a[px][py] >= val)
Union(px*m+py,x*m+y);
}
if(k % val)
continue;
long long len = k / val;
if(len <= num[Find(x*m+y)])
{
memset(b,0,sizeof(b));
memset(vis,0,sizeof(vis));
bfs(x,y,len);
flag = 1;
printf("YES\n");
for(int j = 0; j < n; j++)
{
for(int k = 0; k < m; k++)
printf("%d ",b[j][k]);
printf("\n");
}
break;
}
}
if(!flag)
printf("NO\n");
}
return 0;
}