#include #include #include #include #include #include using namespace std; // #include // using namespace atcoder; // ==================== // デバッグユーティリティ // ==================== #ifdef DEBUG #define COLOR_RESET "\033[0m" #define COLOR_YELLOW "\033[33m" #define COLOR_CYAN "\033[36m" #define COLOR_MAGENTA "\033[35m" #define COLOR_BLACK "\033[30m" #define COLOR_RED "\033[31m" #define COLOR_GREEN "\033[32m" #define COLOR_BLUE "\033[34m" #define COLOR_WHITE "\033[37m" #define STYLE_DIM "\033[2m" // ==================== // 型情報出力 // ==================== // 整数をカンマ区切りに string format_with_commas(unsigned __int128 x) { if (x == 0) return "0"; string s; while (x > 0) { s.push_back('0' + (x % 10)); x /= 10; } reverse(s.begin(), s.end()); string out; int n = s.size(), cnt = 0; for (int i = n - 1; i >= 0; --i) { out.push_back(s[i]); if (++cnt % 3 == 0 && i != 0) out.push_back(','); } reverse(out.begin(), out.end()); return out; } // 整数をカンマなし文字列に string format_plain_digits(unsigned __int128 x) { if (x == 0) return "0"; string s; while (x > 0) { s.push_back('0' + (x % 10)); x /= 10; } reverse(s.begin(), s.end()); return s; } // 浮動小数型 → 科学的記法 string format_float_with_exp(long double x) { if (x == 0.0L) return "0"; int exp = floor(log10(fabsl(x))); long double base = x / powl(10.0L, exp); ostringstream oss; oss << fixed << setprecision(5) << base; return oss.str() + " × 10^" + to_string(exp); } // 整数型 min/max をカンマ区切り+10^n 表記 template string format_int_with_exp(T x) { using U = unsigned __int128; auto make_exp_part = [](const string& plain, bool neg = false) -> string { if (plain == "0") return " (≈ 0 × 10^0)"; int exp = (int)plain.size() - 1; string head; head += plain[0]; if (plain.size() >= 2) { head += "."; head += plain.substr(1, min(2, plain.size() - 1)); } return " (≈ " + string(neg ? "-" : "") + head + " × 10^" + to_string(exp) + ")"; }; if constexpr (std::is_same_v) { return string(x ? "1 (true)" : "0 (false)"); } else if constexpr (std::is_signed_v) { if (x == std::numeric_limits::min()) { U val = (U)((unsigned __int128)std::numeric_limits::max()) + 1; string grouped = format_with_commas(val); string plain = format_plain_digits(val); return "-" + grouped + make_exp_part(plain, true); } bool neg = (x < 0); U val = neg ? U(-(__int128)x) : U(x); string grouped = format_with_commas(val); string plain = format_plain_digits(val); return string(neg ? "-" : "") + grouped + make_exp_part(plain, neg); } else { U val = U(x); string grouped = format_with_commas(val); string plain = format_plain_digits(val); return grouped + make_exp_part(plain, false); } } // 型情報出力 template void debug_typeinfo(const string& name) { cerr << COLOR_CYAN << "Type info for " << name << " ----------" << COLOR_RESET << "\n"; cerr << COLOR_YELLOW << " sizeof : " << COLOR_WHITE << sizeof(T) << " bytes\n"; if constexpr (std::numeric_limits::is_specialized) { if constexpr (std::is_integral_v) { cerr << COLOR_YELLOW << " min : " << COLOR_GREEN << format_int_with_exp(numeric_limits::min()) << COLOR_RESET << "\n"; cerr << COLOR_YELLOW << " max : " << COLOR_GREEN << format_int_with_exp(numeric_limits::max()) << COLOR_RESET << "\n"; } else if constexpr (std::is_floating_point_v) { cerr << COLOR_YELLOW << " min : " << COLOR_GREEN << format_float_with_exp(numeric_limits::min()) << COLOR_RESET << "\n"; cerr << COLOR_YELLOW << " max : " << COLOR_GREEN << format_float_with_exp(numeric_limits::max()) << COLOR_RESET << "\n"; } } else { cerr << " min : (not available)\n"; cerr << " max : (not available)\n"; } cerr << "----------------------------------\n"; } // よく使う型リスト void debug_type_list() { debug_typeinfo("int"); debug_typeinfo("long long"); debug_typeinfo("unsigned long long"); debug_typeinfo<__int128>("__int128"); debug_typeinfo("unsigned __int128"); debug_typeinfo("float"); debug_typeinfo("double"); debug_typeinfo("long double"); debug_typeinfo("char"); debug_typeinfo("bool"); debug_typeinfo("string"); } string trim(const string& s) { size_t first = s.find_first_not_of(" \t"); size_t last = s.find_last_not_of(" \t"); if (first == string::npos) return ""; return s.substr(first, (last - first + 1)); } // pair template ostream& operator<<(ostream& os, const pair& p) { return os << "(" << p.first << ", " << p.second << ")"; } // tuple template void tuple_out_impl(ostream& os, const Tuple& t, index_sequence) { ((os << (Is == 0 ? "" : ", ") << get(t)), ...); } template ostream& operator<<(ostream& os, const tuple& t) { os << "("; tuple_out_impl(os, t, index_sequence_for{}); os << ")"; return os; } // ==================== // 追加のコンテナ出力 // ==================== // multiset template ostream& operator<<(ostream& os, const multiset& s) { os << "{ "; size_t i = 0; for (auto& x : s) { os << x; if (++i < s.size()) os << ", "; } os << " }"; return os; } // unordered_multiset template ostream& operator<<(ostream& os, const unordered_multiset& s) { os << "{ "; size_t i = 0; for (auto& x : s) { os << x; if (++i < s.size()) os << ", "; } os << " }"; return os; } // multimap template ostream& operator<<(ostream& os, const multimap& m) { os << "{ "; size_t i = 0; for (auto& [k, v] : m) { os << k << ": " << v; if (++i < m.size()) os << ", "; } os << " }"; return os; } // unordered_multimap template ostream& operator<<(ostream& os, const unordered_multimap& m) { os << "{ "; size_t i = 0; for (auto& [k, v] : m) { os << k << ": " << v; if (++i < m.size()) os << ", "; } os << " }"; return os; } // deque template ostream& operator<<(ostream& os, const deque& v) { os << "[ "; for (size_t i = 0; i < v.size(); i++) { os << v[i]; if (i + 1 < v.size()) os << ", "; } os << " ]"; return os; } // list template ostream& operator<<(ostream& os, const list& lst) { os << "[ "; bool first = true; for (auto& x : lst) { if (!first) os << ", "; os << x; first = false; } os << " ]"; return os; } // forward_list template ostream& operator<<(ostream& os, const forward_list& lst) { os << "[ "; bool first = true; for (auto& x : lst) { if (!first) os << ", "; os << x; first = false; } os << " ]"; return os; } // array template ostream& operator<<(ostream& os, const array& a) { os << "[ "; for (size_t i = 0; i < N; i++) { os << a[i]; if (i + 1 < N) os << ", "; } os << " ]"; return os; } // set template ostream& operator<<(ostream& os, const set& s) { os << "{ "; size_t i = 0; for (auto& x : s) { os << x; if (++i < s.size()) os << ", "; } os << " }"; return os; } // vector template ostream& operator<<(ostream& os, const vector& v) { os << "[ "; for (size_t i = 0; i < v.size(); i++) { os << v[i]; if (i + 1 < v.size()) os << ", "; } os << " ]"; return os; } template ostream& operator<<(ostream& os, const unordered_set& s) { os << "{ "; size_t i = 0; for (auto& x : s) { os << x; if (++i < s.size()) os << ", "; } os << " }"; return os; } // map template ostream& operator<<(ostream& os, const map& m) { os << "{ "; size_t i = 0; for (auto& [k,v] : m) { os << k << ": " << v; if (++i < m.size()) os << ", "; } os << " }"; return os; } template ostream& operator<<(ostream& os, const unordered_map& m) { os << "{ "; size_t i = 0; for (auto& [k,v] : m) { os << k << ": " << v; if (++i < m.size()) os << ", "; } os << " }"; return os; } // ==================== // vector 判定 // 2次元 vector を debug 用に判定&整形出力 // ==================== template struct is_vector : std::false_type {}; template struct is_vector> : std::true_type {}; // T が vector< vector<...> > なら true template struct is_2d_vector : std::false_type {}; template struct is_2d_vector> : is_vector {}; // T が 1次元 vector なら true template struct is_1d_vector : std::false_type {}; template struct is_1d_vector> : std::bool_constant::value> {}; // debug 表示モード enum class DebugPrintMode { Normal, // いつもの1行表示 Index0, // 0始まり番号つき縦表示 Index1 // 1始まり番号つき縦表示 }; template struct is_set_like : std::false_type {}; template struct is_set_like> : std::true_type {}; template struct is_set_like> : std::true_type {}; template struct is_set_like> : std::true_type {}; template struct is_set_like> : std::true_type {}; // ==================== // map 系判定 // ==================== template struct is_map_like : std::false_type {}; template struct is_map_like> : std::true_type {}; template struct is_map_like> : std::true_type {}; template struct is_map_like> : std::true_type {}; template struct is_map_like> : std::true_type {}; template void print_indexed_map(std::ostream& os, const MapLike& mp, size_t start_index) { os << "\n"; size_t idx = start_index; bool first = true; for (auto&& [k, v] : mp) { if (!first) os << "\n"; os << COLOR_CYAN << idx++ << COLOR_WHITE << ": { " << COLOR_BLUE << k << COLOR_WHITE << ": " << v << " }"; first = false; } } template void print_indexed_set(std::ostream& os, const SetLike& st, size_t start_index) { os << "\n"; size_t idx = start_index; bool first = true; for (const auto& x : st) { if (!first) os << "\n"; os << COLOR_CYAN << idx++ << COLOR_WHITE << ": " << x; first = false; } } template void print_braced_vector(std::ostream& os, const std::vector& v) { os << "{ "; for (size_t j = 0; j < v.size(); ++j) { os << v[j]; if (j + 1 < v.size()) os << ", "; } os << " }"; } // 1次元 vector を番号つきで表示する関数 template void print_indexed_vector(std::ostream& os, const std::vector& v, size_t start_index) { os << "\n"; for (size_t i = 0; i < v.size(); ++i) { if (i == 0) { os << COLOR_BLUE << (start_index + i) << COLOR_WHITE << ":[ " << v[i]; } else { os << ",\n" << COLOR_BLUE << (start_index + i) << COLOR_WHITE << ": " << v[i]; } } os << " ]"; } // 通常変数 template void debug_dispatch(const char* name, const T& x, DebugPrintMode mode = DebugPrintMode::Normal) { size_t start_index = 0; if (mode == DebugPrintMode::Index1) start_index = 1; // 2次元 vector if constexpr (is_2d_vector::value) { cerr << COLOR_YELLOW << name << COLOR_RESET << " :\n"; size_t idx = start_index; for (size_t i = 0; i < x.size(); ++i) { cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : "; print_braced_vector(cerr, x[i]); cerr << COLOR_RESET << "\n"; } } // 1次元 vector else if constexpr (is_1d_vector::value) { if (mode == DebugPrintMode::Index0 || mode == DebugPrintMode::Index1) { cerr << COLOR_YELLOW << name << COLOR_WHITE << " :"; print_indexed_vector(cerr, x, start_index); cerr << COLOR_RESET << "\n"; } else { cerr << COLOR_YELLOW << name << COLOR_WHITE << " : " << x << COLOR_RESET << "\n"; } } // map 系 else if constexpr (is_map_like::value) { if (mode == DebugPrintMode::Index0 || mode == DebugPrintMode::Index1) { cerr << COLOR_YELLOW << name << COLOR_WHITE << " :"; print_indexed_map(cerr, x, start_index); cerr << COLOR_RESET << "\n"; } else { cerr << COLOR_YELLOW << name << COLOR_WHITE << " : " << x << COLOR_RESET << "\n"; } } // set 系 else if constexpr (is_set_like::value) { if (mode == DebugPrintMode::Index0 || mode == DebugPrintMode::Index1) { cerr << COLOR_YELLOW << name << COLOR_WHITE << " :"; print_indexed_set(cerr, x, start_index); cerr << COLOR_RESET << "\n"; } else { cerr << COLOR_YELLOW << name << COLOR_WHITE << " : " << x << COLOR_RESET << "\n"; } } // それ以外 else { cerr << COLOR_YELLOW << name << COLOR_WHITE << " : " << x << COLOR_RESET << "\n"; } } template void debug_pq_impl(const char* name, PQ pq, size_t start_index) { cerr << COLOR_MAGENTA << name << " ----------" << COLOR_RESET << "\n"; size_t idx = start_index; while (!pq.empty()) { cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " << pq.top() << COLOR_RESET << "\n"; pq.pop(); } } template void debug_stack_impl(const char* name, Stack s, size_t start_index) { cerr << COLOR_MAGENTA << name << " ----------" << COLOR_RESET << "\n"; size_t idx = start_index; while (!s.empty()) { cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " << s.top() << COLOR_RESET << "\n"; s.pop(); } } template void debug_queue_impl(const char* name, Queue q, size_t start_index) { cerr << COLOR_MAGENTA << name << " ----------" << COLOR_RESET << "\n"; size_t idx = start_index; while (!q.empty()) { cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " << q.front() << COLOR_RESET << "\n"; q.pop(); } } template void print_indexed_iterable(std::ostream& os, const Iterable& c, size_t start_index) { os << "\n"; size_t idx = start_index; bool first = true; for (const auto& x : c) { if (!first) os << "\n"; os << COLOR_CYAN << idx++ << COLOR_WHITE << ": " << x; first = false; } } // 複数変数 template void debug_single(DebugPrintMode mode, const char* name, const T& x) { debug_dispatch(name, x, mode); } template void debug_multi(DebugPrintMode mode, const char* names, Args&&... args) { stringstream ss(names); string name; ((getline(ss, name, ','), debug_single(mode, trim(name).c_str(), args)), ...); } // メインマクロ #define debug(...) \ do { \ cerr << COLOR_CYAN << "debug ----------<< start" << COLOR_RESET << "\n"; \ debug_multi(DebugPrintMode::Normal, #__VA_ARGS__, __VA_ARGS__); \ } while (0) #define debug_opt(mode, ...) \ do { \ cerr << COLOR_CYAN << "debug ----------<< start" << COLOR_RESET << "\n"; \ debug_multi(mode, #__VA_ARGS__, __VA_ARGS__); \ } while (0) #define debug_idx0(...) \ do { \ cerr << COLOR_CYAN << "debug ----------<< start" << COLOR_RESET << "\n"; \ debug_multi(DebugPrintMode::Index0, #__VA_ARGS__, __VA_ARGS__); \ } while (0) #define debug_idx1(...) \ do { \ cerr << COLOR_CYAN << "debug ----------<< start" << COLOR_RESET << "\n"; \ debug_multi(DebugPrintMode::Index1, #__VA_ARGS__, __VA_ARGS__); \ } while (0) // queue #define debug_queue(q) \ do { \ auto temp = q; int idx = 0; \ cerr << COLOR_MAGENTA << #q << " ----------" << COLOR_RESET << "\n"; \ while (!temp.empty()) { \ cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " \ << temp.front() << COLOR_RESET << "\n"; \ temp.pop(); \ } \ } while (0) // stack #define debug_stack(s) \ do { \ auto temp = s; int idx = 0; \ cerr << COLOR_MAGENTA << #s << " ----------" << COLOR_RESET << "\n"; \ while (!temp.empty()) { \ cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " \ << temp.top() << COLOR_RESET << "\n"; \ temp.pop(); \ } \ } while (0) // priority_queue #define debug_pq(pq) \ do { \ auto temp = pq; int idx = 0; \ cerr << COLOR_MAGENTA << #pq << " ----------" << COLOR_RESET << "\n"; \ while (!temp.empty()) { \ cerr << COLOR_CYAN << idx++ << COLOR_WHITE << " : " \ << temp.top() << COLOR_RESET << "\n"; \ temp.pop(); \ } \ } while (0) #else #define debug(...) #define debug_opt(...) #define debug_idx0(...) #define debug_idx1(...) #define debug_queue(q) #define debug_stack(s) #define debug_pq(pq) #endif // // 型情報出力 // #include // template // void debug_typeinfo(const string& name) { // using boost::typeindex::type_id_with_cvr; // cout << COLOR_CYAN << "Type info for " << name << " ----------" << COLOR_RESET << "\n"; // // cout << " type : " << type_id_with_cvr().pretty_name() << "\n"; // // cout << " sizeof : " << sizeof(T) << " bytes\n"; // cout << COLOR_YELLOW << " type : " << COLOR_WHITE << type_id_with_cvr().pretty_name() << "\n"; // cout << COLOR_YELLOW << " sizeof : " << COLOR_WHITE << sizeof(T) << " bytes\n"; // if constexpr (std::numeric_limits::is_specialized) { // if constexpr (std::is_integral_v) { // cout << COLOR_YELLOW << " min : " << COLOR_GREEN << format_int_with_exp(numeric_limits::min()) << COLOR_RESET << "\n"; // cout << COLOR_YELLOW << " max : " << COLOR_GREEN << format_int_with_exp(numeric_limits::max()) << COLOR_RESET << "\n"; // // cout << " min : " << format_int_with_exp(numeric_limits::min()) << "\n"; // // cout << " max : " << format_int_with_exp(numeric_limits::max()) << "\n"; // } else if constexpr (std::is_floating_point_v) { // cout << COLOR_YELLOW << " min : " << COLOR_GREEN << format_float_with_exp(numeric_limits::min()) << COLOR_RESET << "\n"; // cout << COLOR_YELLOW << " max : " << COLOR_GREEN << format_float_with_exp(numeric_limits::max()) << COLOR_RESET << "\n"; // // cout << " min : " << format_float_with_exp(numeric_limits::min()) << "\n"; // // cout << " max : " << format_float_with_exp(numeric_limits::max()) << "\n"; // } // } else { // cout << " min : (not available)\n"; // cout << " max : (not available)\n"; // } // cout << "----------------------------------\n"; // } using ll = long long; [[maybe_unused]] const int INF = 1e9; // 非常に大きい値(= 到達不能な値) [[maybe_unused]] const long long LINF = 1e18; // long long 用の無限 [[maybe_unused]] const int NINF = -INF; // 非常に小さい値(最小化の比較など) // #include // const int INF = std::numeric_limits::max()/2; // +∞ 代用 // const int NEG = std::numeric_limits::min()/2; // −∞ 代用 // const ll LINF = std::numeric_limits::max()/4; // 64bit 版 // /2 /4 しておくと 加算してもオーバーフローしない // long long gcd(long long a, long long b){ // while (b != 0){ // long long r = a % b; // a = b; // b = r; // } // return a; // 最終的に最大公約数が入っている // } // long long lcm(long long a, long long b){ // // 先に a で割るとオーバーフロー防止 // // return a / gcd(a, b) * b; // // N (10^18 以上) → long long では危険 // return ( (__int128)a / gcd(a, b) ) * b; // } // ==================== // 進数 // ==================== // #include // #include // bitsetを使うために必要 // #include // setw(10) を使うのに必要 // using namespace std; // -------------------------------------------50| void sinsu() { ios::sync_with_stdio(false); cin.tie(nullptr); // int n = 0; cout << "進数表" << endl; for(int n = 0; n <= 255; ++n){ cout << setw(10) <(n) // 桁数<8> // << endl; << '\n'; } return; } // ==================== // main 部分 // ==================== // https://atcoder.jp/contests/adt_easy_20231130_2/tasks // -------------------------------------------50| // #include // using namespace std; // using ll = long long; #include using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N,M; cin >> N >> M; vector S(N); for(auto& s:S)cin >> s; debug_idx0(S); queue> dot; for(int i = 0; i < N; ++i){ for(int j = 0; j < M; ++j){ if(S[i][j] == '.'){ dot.push({i,j}); } } } debug_queue(dot); if(!dot.empty()){ int checkCon = 0; while(true){ // cerr << "# ループ開始 -------------------------------" << '\n'; auto A = dot.front(); dot.pop(); // debug_queue(dot); int i = A.first; int j = A.second; // debug(i,j,N); if(N == i+1){ dot.push({i,j}); checkCon++; if(checkCon == dot.size())break; continue; } if(S[i+1][j] =='#'){ S[i][j] = '#'; S[i+1][j] = '.'; dot.push({i+1,j}); checkCon = 0; // カウントリセット }else{ dot.push({i,j}); // 1周チェック用 ------| checkCon++; if(checkCon == dot.size())break; } } while(true){ auto A = dot.front(); dot.pop(); int i = A.first; int j = A.second; if(M == j+1){ dot.push({i,j}); checkCon++; if(checkCon == dot.size())break; continue; } if(S[i][j+1] =='#'){ S[i][j] = '#'; S[i][j+1] = '.'; dot.push({i,j+1}); checkCon = 0; // カウントリセット }else{ dot.push({i,j}); // 1周チェック用 ------| checkCon++; if(checkCon == dot.size())break; } } } for(int i = 0; i < N; ++i){ cout << S[i] << '\n'; } return 0; } /* デバッグで使えるもの --- // 型例 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ int x = 3;r long long y = 100; double z = 2.5; string s = "abc"; pair p = {2, 5}; tuple t = {1, "cat", 3.14}; vector v = {10, 20, 30}; vector> g = {{1, 2}, {3}, {4, 5}}; set st = {3, 1, 4}; stack stc; stc.push(10); stc.push(20); stc.push(30); unordered_set us = {8, 2, 5}; map mp = {{1, "one"}, {2, "two"}}; unordered_map ump = {{3, "three"}, {4, "four"}}; deque dq = {10, 20, 30}; list lst = {10, 20, 30}; forward_list flst = {10, 20, 30}; array a = {10, 20, 30}; multiset ms = {3, 1, 3, 2}; multimap mm; mm.emplace(1, "one"); mm.emplace(1, "uno"); mm.emplace(2, "two"); \\ デバッグの書き方_____________________ debug(x,y,z,s,p,t,v,g,st,us,mp,ump,dq,lst,flst,a,ms,mm); debug_idx0(v); debug_idx1(v); debug_idx0(mp); debug_idx1(mp); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // 型例 以下は下記でバッグで出力できる~~~~~ queue q; q.push(10); q.push(20); q.push(30); debug_queue(q); stack st2; st2.push(10); st2.push(20); st2.push(30); debug_stack(st2); priority_queue pq; pq.push(5); pq.push(1); pq.push(9); \\ デバッグの書き方_____________________ debug_pq(pq); debug_idx0(v, mp, ump, us, st); debug_queue(q); debug_stack(st2); debug_pq(pq); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // 型情報 ____________________________ debug_typeinfo("int"); debug_typeinfo("double"); debug_type_list(); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ /* x が増えれば y も増えるとき,その関数は単調増加と言う 広義単調増加 x1 < x2 ならば f(x1) <= f(x2) 狭義単調増加 x1 < x2 ならば f(x1) < f(x2) */ //dbg- //ord- // ./c < in.txt