#include #include #include #include using namespace std; struct Pos { int x; int y; }; enum Dir { DOWN, RIGHT }; struct Op{ int idx; int len; pair pos; }; const int N = 60; void Transpose(const array, N>& arr, array, N>& arr_t) { for (int i = 0; i < arr.size(); i++) { for (int j = 0; j < arr.size(); j++) { arr_t[j][i] = arr[i][j]; } } } int main() { array, N> arr, arr_t; array ops; int n, k; cin >> n >> k; for (int i = 0; i < k; i++) { Op p; p.idx = i; cin >> p.len; ops[i] = p; } string s; for (int i = 0; i < n; i++) { cin >> s; for (int j = 0; j < n; j++) { arr[i][j] = (s[j] == '0' ? 0 : 1); } } Transpose(arr, arr_t); std::sort(ops.begin(), ops.end(), [](const Op& l, const Op& r) { return l.len > r.len; }); for (Op& op : ops) { bitset bs; for (int i = 0; i < op.len; i++) { bs[i] = 1; } int best_e = 0; pair best_pos; for (int i = 0; i < N; i++) { for (int j = 0; j < N - (op.len-1); j++) { int e_x = (arr[i] & (bs << j)).count(); // 長方形内の黒の数 int e_y = (arr_t[i] & (bs << j)).count(); int e = max(e_x, e_y); if (e > best_e) { best_e = e; if (e_x > e_y) { best_pos = make_pair(Pos{ j, i }, RIGHT); } else { best_pos = make_pair(Pos{ i, j }, DOWN); } } } } // 操作を適用 switch (best_pos.second) { case Dir::RIGHT: arr[best_pos.first.y] ^= bs << best_pos.first.x; Transpose(arr, arr_t); break; case Dir::DOWN: arr_t[best_pos.first.x] ^= bs << best_pos.first.y; Transpose(arr_t, arr); break; } op.pos = best_pos; } std::sort(ops.begin(), ops.end(), [](const Op& l, const Op& r) { return l.idx < r.idx; }); for (Op op : ops) { int x1 = op.pos.first.x; int y1 = op.pos.first.y; int x2 = x1; int y2 = y1; switch (op.pos.second) { case Dir::RIGHT: x2 += (op.len-1); break; case Dir::DOWN: y2 += (op.len-1); break; } cout << y1+1 << " " << x1+1 << " " << y2+1 << " " << x2+1 << endl; } return 0; }