您的位置:首页 > 其它

Codeforces 659F F - Polycarp and Hay

2017-08-22 16:42 344 查看
题意 : 

题意:给你n, m (1 ≤ n,m ≤ 1000) and k (1 ≤ k ≤ 10^18),n,m表示一个 n*m的矩阵,矩阵中的每个元素小于等于10^9,问能不能构成另外一个矩阵。

这个矩阵里面相同位置的数只能小于等于原来矩阵里面相同位置的数。并且在这个矩阵中存在一个连通块这个连通块中的数都等于这个连通块中最小的数,并且

连通块的权值和恰好等于k

让你输出一个可行解。

solution : 对于这个题目用并查集维护连通块的最大数目,讲矩阵中的数从大到小排序,(因为这样排序可以使得每次得到一个新的数都满足它小于等于前面所有的数,这样就可以直接加入到并查集中 ) 每次选择一个数,看看这个数是不是k的因子 ,如果是就判断这个数乘以它所在集合里数的个数是不是大于等于k的,如果是我们就找到了一个可行的位置,用bfs输出答案即可。

 坑点:这个题最后可能只剩下一个数。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define ll long long
using namespace std;
const int maxn = 1e6 + 10;
struct node {
int x,y;
ll num;
}a[maxn];
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int cnt = 0;
int n,m;
ll k;
bool vis[1005][1005] = {0};
ll g[1005][1005] = {0};
int p[maxn] = {0};
ll sum[maxn] = {0};
bool cmp (node a,node b) {
return a.num > b.num;
}
int find (int x) {
if (x == p[x])return x;
return p[x] = find (p[x]);
}
void u (int x,int y) {
x = find (x);
y = find (y);
if (x != y) {
p[x] = y;
sum[y] += sum[x];
sum[x] = 0;
}
}
void bfs (int pos) {
ll temp = (k + 0.5) / a[pos].num;
int x = a[pos].x;
int y = a[pos].y;
memset (vis,0,sizeof (vis));
vis[x][y] = 1;
queue <node> q;
q.push (a[pos]);
while (!q.empty()) {
node u = q.front();
q.pop ();
for (int i = 0;i < 4; ++ i) {
int xx = u.x + dx[i];
int yy = u.y + dy[i];
if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && g[xx][yy] >= g[x][y] && !vis[xx][yy]) {
vis[xx][yy] = 1;
temp --;
if (temp == 1) return ;
q.push ({xx,yy,0});
}
}
}
return ;
}
int main () {
ios_base :: sync_with_stdio(false);
int ok = 0;
cin >> n >> m >> k;
for (int i = 1;i <= n; ++ i) {
for (int j = 1;j <= m; ++ j) {
a[cnt].x = i;
a[cnt].y = j;
cin >> a[cnt].num;
g[i][j] = a[cnt].num;
cnt ++;
}
}
sort (a,a + cnt,cmp);
for (int i = 0;i < maxn; ++ i) {
p[i] = i;
sum[i] = 1;
}
for (int i = 0;i < cnt ; ++ i) {
vis[a[i].x][a[i].y] = 1;
if (a[i].num == k) {
memset (vis,0,sizeof (vis));
cout << "YES" << endl;
vis[a[i].x][a[i].y] = 1;
for (int u = 1;u <= n; ++ u) {
for (int j = 1;j <= m; ++ j) {
if (vis[u][j]) {
cout << a[i].num << ' ';
}
else {
cout << 0 << ' ';
}
}
cout << endl;
}
return 0;
}
for (int j = 0;j < 4; ++ j) {
int xx = a[i].x + dx[j];
int yy = a[i].y + dy[j];
if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && vis[xx][yy]) {
u ((xx - 1) * m + yy,(a[i].x - 1) * m + a[i].y);
if (k % a[i].num == 0) {
int fa = p[(a[i].x - 1) * m + a[i].y];
if (sum[fa] * a[i].num >= k) {
ok = 1;
cout << "YES" << endl;
bfs (i);
for (int u = 1;u <= n; ++ u) {
for (int j = 1;j <= m; ++ j) {
if (vis[u][j]) {
cout << a[i].num << ' ';
}
else {
cout << 0 << ' ';
}
}
cout << endl;
}
return 0;
}
}
}
}
}
cout << "NO" << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息