Codeforces Round #777 Div 2 – Problem C

Original problem statement taken from this link.

Madoka and the Childish Pranks

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

Madoka as a child was an extremely capricious girl, and one of her favorite pranks was drawing on her wall. According to Madoka’s memories, the wall was a table of N rows and M columns, consisting only of zeroes and ones. The coordinate of the cell in the i-th row and the j-th column (1 <= i <= N, 1 <= j <= M) is (i,j).

One day she saw a picture “Mahou Shoujo Madoka Magica” and decided to draw it on her wall. Initially, the Madoka’s table is a table of size N x M filled with zeroes. Then she applies the following operation any number of times:

Madoka selects any rectangular subtable of the table and paints it in a chess coloring (the upper left corner of the subtable always has the color 0). Note that some cells may be colored several times. In this case, the final color of the cell is equal to the color obtained during the last repainting.

White color means 0, black means 1. So, for example, the table in the first picture is painted in a chess coloring, and the others are not.

For better understanding of the statement, we recommend you to read the explanation of the first test.

Help Madoka and find some sequence of no more than N * M operations that allows you to obtain the picture she wants, or determine that this is impossible.

Input

Each test contains multiple test cases. The first line contains a single integer t (1 <= t <= 10) — the number of test cases. Description of the test cases follows.

The first line of each test case contains two integers N and M (1 <= N, M <= 100) — the size of the table. Each of the following N lines contains a string of length M consisting only of 1 and 0 — description of the picture that Madoka wants to obtain.

Output

If it is impossible to obtain the given picture, print −1.

Otherwise, print in the first line a single integer Q (0 <= Q <= N * M) — the number of operations you need to obtain the picture. Note that you do not need to minimize the number of operations.

Then for each operation (in the order of execution) print a single line containing four numbers — the coordinates of the upper-left corner and the lower-right corner of the rectangle.

Example input:

4
4 5
01000
10100
01010
00110
2 3
001
010
3 3
110
101
000
1 1
0

Example output:

4
1 1 3 3
3 3 4 4
4 3 4 4
4 2 4 3
1
1 2 2 3
-1
0

Note:

The description of the first test case is below.

In the third test case, it is impossible to paint the desired picture.

In the fourth test case, the initial table is already the desired picture.

Solution

This is how one possible implementation would look like:

#include <iostream>
#include <vector>

using namespace std;

int mainC(int argc, const char * argv[]) {
    
    int t;
    cin >> t;
    while (t--) {
        int n, m, i, j;
        cin >> n  >> m;
        vector< vector<bool> > a(n, vector<bool>(m, 0));
        char k;
        for (int i=0;i<n;i++) {
            for (int j=0;j<m;j++) {
                cin >> k;
                a[i][j] = (k == '0') ? false : true;
            }
        }
        
        // process each row right to left
        vector<pair<int,int> > s1, s2;
        vector< vector<bool> > b(n, vector<bool>(m, 0));
        for (i=n-1;i>=0;i--) {
            for (j=m-1;j>0;j--) {
                if (b[i][j] == 0 && a[i][j] == 1) {
                    b[i][j] = 1;
                    b[i][j-1] = 0;
                    s1.push_back({i+1, j});
                    s2.push_back({i+1, j+1});
                }
            }
        }
        
        // process first column bottom to top
        for (i=n-1;i>0;i--) {
            if (b[i][0] == 0 && a[i][0] == 1) {
                b[i][0] = 1;
                b[i-1][0] = 0;
                s1.push_back({i, 1});
                s2.push_back({i+1, 1});
            }
        }
        
        if (a[0][0] != b[0][0]) cout << -1 << endl;
        else {
            cout << s1.size() << endl;
            for (int i=0;i<s1.size();i++)
                cout << s1[i].first << " " << s1[i].second << " " << s2[i].first << " " << s2[i].second << endl;
        }
    }
    
    return 0;
}

Leave a Comment