結果
| 問題 |
No.307 最近色塗る問題多くない?
|
| コンテスト | |
| ユーザー |
dnish
|
| 提出日時 | 2018-07-02 22:10:27 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,451 bytes |
| コンパイル時間 | 2,128 ms |
| コンパイル使用メモリ | 186,572 KB |
| 実行使用メモリ | 17,896 KB |
| 最終ジャッジ日時 | 2024-07-01 01:40:08 |
| 合計ジャッジ時間 | 5,588 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 13 WA * 23 |
ソースコード
#include "bits/stdc++.h"
#define REP(i, n, N) for(ll i=(n); i<(N); i++)
#define RREP(i, n, N) for(ll i=(N-1); i>=n; i--)
#define CK(n, a, b) ((a)<=(n)&&(n)<(b))
#define ALL(v) (v).begin(),(v).end()
#define MCP(a, b) memcpy(b,a,sizeof(b))
#define p(s) cout<<(s)<<endl
#define p2(a, b) cout<<(a)<<" "<<(b)<<endl
#define v2(T) vector<vector<T>>
typedef long long ll;
using namespace std;
const ll mod = 1e9 + 7;
const ll inf = 1e18;
const int MAX_N = 200210;
int field[210][210];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
int H, W, Q;
struct UnionFind {
int par[MAX_N]; // 親ノードの番号
int deph[MAX_N]; // ノードの深さ
int color[MAX_N];
vector<int> neigh[MAX_N];
UnionFind(int n) {
fill(par, par + MAX_N, -1);
for (int i = 0; i < n; i++) {
par[i] = i;
deph[i] = 0;
color[i] = field[i / 1000][i % 1000];
if(i%1000<W-1)neigh[i].push_back(i+1);
if(i%1000>0)neigh[i].push_back(i-1);
if(i/1000<H-1)neigh[i].push_back(i+1000);
if(i/1000>0)neigh[i].push_back(i-1000);
/* 持っておくデータにおいて初期化が必要な場合
// istree[i] = true;
*/
}
}
int find(int x) {
if (par[x] == x) {
return x;
} else {
return par[x] = find(par[x]);
}
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
/* 同じグループに属しているときの処理
// istree = false;
*/
return;
}
if (deph[x] < deph[y]) {
par[x] = par[y];
color[x] = color[y];
copy(neigh[y].begin(), neigh[y].end(), back_inserter(neigh[x]));
sort(neigh[y].begin(), neigh[y].end());
neigh[y].erase(unique(neigh[y].begin(), neigh[y].end()), neigh[y].end());
/* ルートをyとする時の処理
*/
} else {
par[y] = par[x];
color[y] = color[x];
copy(neigh[x].begin(), neigh[x].end(), back_inserter(neigh[y]));
sort(neigh[x].begin(), neigh[x].end());
neigh[x].erase(unique(neigh[x].begin(), neigh[x].end()), neigh[x].end());
if (deph[x] == deph[y]) deph[x]++;
/* ルートをxとする時の処理
*/
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
void chcol(int x, int col) {
int pa=find(x);
set<int> s;
for(auto n:neigh[pa]){
int pa2=find(n);
if(s.find(pa2)!=s.end()) continue;
s.insert(pa2);
}
for(auto pa2:s){
unite(pa,pa2);
}
color[find(pa)] = col;
}
};
int main() {
cin >> H >> W;
REP(i, 0, H) REP(j, 0, W) cin >> field[i][j];
UnionFind uf(200210);
bool visited[210][210];
REP(i, 0, H) REP(j, 0, W) visited[i][j] = false;
queue<pair<int, int>> q;
REP(i, 0, H) {
REP(j, 0, W) {
if (visited[i][j]) continue;
int col = field[i][j];
q.push({i, j});
while (!q.empty()) {
int cur_y = q.front().first;
int cur_x = q.front().second;
q.pop();
if (visited[cur_y][cur_x]) continue;
visited[cur_y][cur_x] = true;
REP(k, 0, 4) {
//REP(k,0,8){
int next_y = cur_y + dy[k];
int next_x = cur_x + dx[k];
if (!CK(next_y, 0, H) || !CK(next_x, 0, W)) continue;
if (field[next_y][next_x] != col) continue;
if (!visited[next_y][next_x]) { //未到達の座標だけpush.
q.push({next_y, next_x});
uf.unite(i * 1000 + j, next_y * 1000 + next_x);
}
}
}
}
}
cin >> Q;
REP(q, 0, Q) {
int y, x, c;
cin >> y >> x >> c;
y--;
x--;
int pa = uf.find(y * 1000 + x);
if(uf.color[uf.find(y * 1000 + x)]!=c) uf.chcol(y * 1000 + x, c);
}
REP(i, 0, H) {
REP(j, 0, W) {
cout << uf.color[uf.find(i * 1000 + j)];
if (j < W - 1) cout << " ";
}
cout << endl;
}
return 0;
}
dnish