結果
| 問題 |
No.1427 Simplified Tetris
|
| コンテスト | |
| ユーザー |
carrot46
|
| 提出日時 | 2021-03-12 23:21:25 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 121 ms / 2,000 ms |
| コード長 | 4,956 bytes |
| コンパイル時間 | 1,823 ms |
| コンパイル使用メモリ | 183,488 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-14 13:55:24 |
| 合計ジャッジ時間 | 3,759 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 37 |
ソースコード
#include <bits/stdc++.h>
//#include <chrono>
//#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()
using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;
ll N,M,H,W,Q,K,A,B;
string S;
using P = pair<ll, ll>;
const ll INF = (1LL<<60);
template<class T> bool chmin(T &a, const T b){
if(a > b) {a = b; return true;}
else return false;
}
template<class T> bool chmax(T &a, const T b){
if(a < b) {a = b; return true;}
else return false;
}
template<class T> void my_printv(std::vector<T> v,bool endline = true){
if(!v.empty()){
for(std::size_t i{}; i<v.size()-1; ++i) std::cout<<v[i]<<" ";
std::cout<<v.back();
}
if(endline) std::cout<<std::endl;
}
struct edge{
int to, rev;
ll cap;
edge(){}
edge(int a, ll b, int c){
to = a;
cap = b;
rev = c;
}
};
using ve = vector<edge>;
void add_edge(int from, int to, ll cap, vector<ve> &G, bool directed = true){
G[from].emplace_back(to, cap, (int)G[to].size());
G[to].emplace_back(from, directed ? 0 : cap, (int)G[from].size() - 1);
}
void bfs(int s, vector<ve> &G, vector<int> &level){
queue<int> que;
level[s] = 0;
que.push(s);
while(!que.empty()){
int v = que.front(); que.pop();
for(edge &e : G[v]){
if(e.cap > 0 && chmin(level[e.to], level[v] + 1)){
que.push(e.to);
}
}
}
}
ll dfs(int v, int t, ll f, vector<ve> &G, vector<int> &level, vector<int> &iter){
if(v == t) return f;
for(int &i = iter[v]; i < G[v].size(); ++i){
edge &e = G[v][i];
if(e.cap > 0 && level[v] < level[e.to]){
ll d = dfs(e.to, t, min(f, e.cap), G, level, iter);
if(d > 0){
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
ll dinic(int s, int t, vector<ve> &G){
ll res = 0;
int sz = G.size();
for( ; ; ){
vector<int> level(sz, INT_MAX), iter(sz, 0);
bfs(s, G, level);
if(level[t] == INT_MAX) return res;
ll f;
while((f = dfs(s, t, INF, G, level, iter)) > 0) res += f;
}
}
void no(){
cout<<"No"<<endl;
exit(0);
}
vector<string> input;
int last = -1;
string T;
bool bipartite_matching(vector<string> &res){
const int st = H * W, gl = H * W + 1;
const vector<int> di = {-1, 0, 1, 0}, dj = {0, -1, 0, 1};
vector<ve> G(H * W + 2);
int flow_num{};
rep(i, H) {
rep(j, W){
if(res[i][j] == '.') continue;
++flow_num;
int id = i * W + j;
if((i + j)&1){
add_edge(st, id, 1, G);
rep(k, 4){
int ni = i + di[k], nj = j + dj[k];
if(ni >= 0 && ni < H && nj >= 0 && nj < W && res[ni][nj] == '#'){
add_edge(id, ni * W + nj, 1, G);
}
}
}else{
add_edge(id, gl, 1, G);
}
}
}
if(flow_num&1) return false;
flow_num >>= 1;
int actually_flow_num = dinic(st, gl, G);
if(flow_num != actually_flow_num) return false;
bool dai = false;
int char_num = 0;
rep(i, H) {
rep(j, W) {
if (res[i][j] == '.') continue;
int id = i * W + j;
if((i + j)&1) {
for (edge &e : G[id]) {
if (e.cap == 0 && e.to != st) {
res[i][j] = res[e.to / W][e.to % W] = char((dai ? 'A' : 'a') + char_num);
if ((++char_num) == 25) {
char_num = 0;
dai = true;
}
break;
}
}
}
}
}
return true;
}
bool dfs(int res_id, int input_id, vector<string> &res){
//cout<<res_id<<' '<<input_id<<endl;
if(res_id == -1) return input_id == last && bipartite_matching(res);
if(input_id != last){
res[res_id] = input[input_id];
if(dfs(res_id - 1, input_id - 1, res)) return true;
}
res[res_id] = T;
if(dfs(res_id - 1, input_id, res)) return true;
res[res_id] = S;
return dfs(res_id - 1, input_id, res);
}
int main(){
cin.tie(nullptr);
ios::sync_with_stdio(false);
cin>>H>>W;
S = string(W, '.');
T = string(W, '#');
vector<string> res(H, S);
input.resize(H);
rep(i, H) {
cin>>input[i];
if(input[i] == S){
if(last != i - 1) no();
last = i;
}
if(input[i] == T) no();
}
if(dfs(H - 1, H - 1, res)){
cout<<"Yes"<<endl;
rep(i, H) cout<<res[i]<<endl;
}else{
no();
}
}
carrot46