結果

問題 No.307 最近色塗る問題多くない?
ユーザー cormorancormoran
提出日時 2016-03-01 22:28:14
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 4,629 bytes
コンパイル時間 1,438 ms
コンパイル使用メモリ 95,892 KB
実行使用メモリ 8,328 KB
最終ジャッジ日時 2023-10-24 19:24:24
合計ジャッジ時間 13,782 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,372 KB
testcase_01 AC 1 ms
4,348 KB
testcase_02 AC 1 ms
4,348 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 AC 135 ms
4,348 KB
testcase_08 WA -
testcase_09 WA -
testcase_10 AC 67 ms
4,348 KB
testcase_11 AC 151 ms
4,348 KB
testcase_12 WA -
testcase_13 AC 313 ms
4,348 KB
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 AC 2 ms
4,348 KB
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 AC 403 ms
4,348 KB
testcase_28 WA -
testcase_29 AC 28 ms
4,348 KB
testcase_30 TLE -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

//  yukicoder -  - 307  / 2016-03-01
#include<iostream>
#include<vector>
#include<cassert>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<tuple>
using namespace std;

typedef long long ll;
typedef pair<ll,ll> pll;
typedef ll int__;
#define rep(i,j) for(int__ i=0;i<(int__)(j);i++)
#define repeat(i,j,k) for(int__ i=(j);i<(int__)(k);i++)
#define all(v) v.begin(),v.end()

template<typename T>ostream& operator << (ostream &os , const vector<T> &v){
    rep(i,v.size()) os << v[i] << (i!=v.size()-1 ? " " : "\n"); return os;
}
template<typename T>istream& operator >> (istream &is , vector<T> &v){
    rep(i,v.size()) is >> v[i]; return is;
}

#ifdef DEBUG
void debug(){ cerr << endl; }
#endif
template<class F,class...R> void debug(const F &car,const R&... cdr){
#ifdef DEBUG
    cerr << car << " "; debug(cdr...);
#endif
}


const int dx[] = { 0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};

struct UnionFind{
    int n;
    vector<int> p;
    UnionFind(int nn):n(nn+1){
        p.resize(n);
        rep(i,n) p[i] = i;
    }
    int root(int x){
        if(p[x] == x) return x;
        else return p[x] = root(p[x]);
    }
    void unite(int x,int y){
        x = root(x);
        y = root(y);
        if(x != y) p[y] = x;
    }
    bool query(int x,int y){
        return root(x) == root(y);
    }
};


// ---------- --------- ---------
int H, W;
vector<vector<int>> G;


int ptoi(int x, int y){
    return y * W + x;
}

bool is_in_field(int x, int y){
    return 0 <= x and x < W and 0 <= y and y < H;
}

void scroll(UnionFind &ut, vector<int> color, int x, int y){
    int xx = x, yy = y;
    // up!
    while(true){
        int nx = x + dx[0];
        int ny = y + dy[0];
        if(is_in_field(nx, ny) and ut.query(ptoi(x,y), ptoi(nx,ny))){
            x = nx;
            y = ny;
        } else break;
    }
    vector<vector<bool>> visited(H, vector<bool>(W));
    int nxt_dir = 0;
    stack<int> merge;
    // walk boundary
    while(true){
        if(visited[y][x]){
            rep(i, 2){
                int nx1 = x + dx[i], nx2 = x + dx[(i+2)%4];
                int ny1 = y + dy[i], ny2 = y + dy[(i+2)%4];
                if(not( is_in_field(nx1, ny1) and
                        ut.query(ptoi(x,y),ptoi(nx1,ny1))) and
                   not( is_in_field(nx2, ny2) and
                        ut.query(ptoi(x,y),ptoi(nx2,ny2)))
                   ){
                    rep(j, 2){
                        int nx = x + dx[(i+1+2*j)%4], ny = y + dy[(i+1+2*j)%4];
                        if(is_in_field(nx, ny) and not visited[ny][nx]){
                            x = nx;
                            y = ny;
                            goto START;
                        }
                    }
                }
            }
            break;
        }
  START:
        
        visited[y][x] = true;
        rep(d, 4){
            int nd = (nxt_dir + d) % 4;
            int nx = x + dx[nd];
            int ny = y + dy[nd];
            if(is_in_field(nx, ny)){
                if(ut.query(ptoi(x,y),ptoi(nx,ny))){
                    x = nx;
                    y = ny;
                    nxt_dir = (nd + 3) % 4;
                    break;
                } else {
                    if(color[ut.root(ptoi(x,y))] == color[ut.root(ptoi(nx,ny))]){
                        merge.push(ptoi(nx,ny));
                    }
                }
            }
        }
    }
    while(not merge.empty()){
        ut.unite(ptoi(xx, yy), merge.top());
        merge.pop();
    }
}

bool solve(){
    cin >> H >> W;
    G.resize(H, vector<int>(W));
    rep(i, H) cin >> G[i];

    UnionFind ut(H*W);
    vector<int> color(H*W);
    rep(y, H) rep(x, W) color[ptoi(x, y)] = G[y][x];
            
    rep(y,H){
        rep(x, W){
            rep(dir, 4){
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(0 <= nx and nx < W and
                   0 <= ny and ny < H){
                    if(G[y][x] == G[ny][nx]){
                        ut.unite(ptoi(x, y), ptoi(nx, ny));
                    }
                }
            }
        }
    }

    int Q; cin >> Q;
    rep(i, Q){
        int y, x, c; cin >> y >> x >> c;
        y--; x--;
        int p = ptoi(x, y);
        color[ut.root(p)] = c;
        scroll(ut, color, x, y);
    }

    rep(y, H){
        rep(x, W){
            cout << color[ut.root(ptoi(x, y))] << (x != W-1 ? " " : "\n");
        }
    }
    
    return false;
}

int main()
{
    ios::sync_with_stdio(false);
    while(solve());
    return 0;
}
0