結果
| 問題 |
No.2946 Puyo
|
| コンテスト | |
| ユーザー |
rotti_coder
|
| 提出日時 | 2024-07-03 05:05:11 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 83 ms / 2,000 ms |
| コード長 | 2,090 bytes |
| コンパイル時間 | 858 ms |
| コンパイル使用メモリ | 80,364 KB |
| 最終ジャッジ日時 | 2025-02-22 01:51:49 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 45 |
ソースコード
#include<iostream>
#include<vector>
using namespace std;
class UnionFind {
public:
//配列のでかさは調整
int par[1000009];
int siz[1000009];
// N 頂点の Union-Find を作成
void init(int N) {
for (int i = 1; i <= N; i++) par[i] = -1; // 最初は親が無い
for (int i = 1; i <= N; i++) siz[i] = 1; // 最初はグループの頂点数が 1
}
// 頂点 x の根を返す関数
int root(int x) {
while (true) {
if (par[x] == -1) break; // 1 個先(親)がなければ、ここが根
x = par[x]; // 1 個先(親)に進む
}
return x;
}
// 要素 u と v を統合する関数
void unite(int u, int v) {
int RootU = root(u);
int RootV = root(v);
if (RootU == RootV) return; // u と v が同グループのときは処理を行わない
if (siz[RootU] < siz[RootV]) {
par[RootU] = RootV;
siz[RootV] = siz[RootU] + siz[RootV];
}
else {
par[RootV] = RootU;
siz[RootU] = siz[RootU] + siz[RootV];
}
}
// 要素 u と v が同一のグループかどうかを返す関数
bool same(int u, int v) {
if (root(u) == root(v)) return true;
return false;
}
//要素nが属しているグループのデカさ
int dekasa(int n){
return siz[root(n)];
}
};
int main()
{
int h,w;
cin >> h >> w;
vector<vector<char>>grid(h,vector<char>(w));
for(int i=0;i<h;i++)for(int j=0;j<w;j++)cin >> grid[i][j];
vector<vector<int>>num(h,vector<int>(w));
for(int i=0;i<h;i++)for(int j=0;j<w;j++)num[i][j]=i*w+j+1;
UnionFind UF;
UF.init(h*w);
for(int i=0;i<h;i++)for(int j=0;j<w;j++){
if(i-1>=0 && grid[i-1][j]==grid[i][j])UF.unite(num[i][j],num[i-1][j]);
if(j+1<w && grid[i][j]==grid[i][j+1])UF.unite(num[i][j],num[i][j+1]);
if(i+1<h && grid[i][j]==grid[i+1][j])UF.unite(num[i][j],num[i+1][j]);
if(j-1>=0 && grid[i][j]==grid[i][j-1])UF.unite(num[i][j],num[i][j-1]);
}
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
if(UF.dekasa(num[i][j])>=4)cout << ".";
else cout << grid[i][j];
}
cout << endl;
}
}
rotti_coder