Official

C - X drawing Editorial by en_translator


First, consider which squares are painted by the first operation:

  • for every integer \(k\) such that \(\max(1-A,1-B)\leq k\leq \min(N-A,N-B)\), paint \((A+k,B+k)\) black.

If we try to naively simulate this, there will be at most \(10^{18}\) squares to be painted, which is too enormous to finish in time. So we consider rephrasing this condition. First, this is equivalent to:

  • for every integer such that \(1-A\leq k \leq N-A\) and \(1-B \leq k \leq N-B\), paint \((A+k,B+k)\) black.

Therefore, it is rephrase to:

  • for every integer such that \(1\leq A+k \leq N\) and \(1 \leq B+k \leq N\), paint \((A+k,B+k)\) black.

What we want to know is in the range of \(P\leq i \leq Q\) and \(R\leq j \leq S\), and by \(1\leq P\leq Q \leq N\) and \(1\leq R\leq S \leq N\), so this operation can be replaced with

  • for every integer such that \(P\leq A+k \leq Q\) and \(R \leq B+k \leq S\), paint \((A+k,B+k)\) black

without changing the answer. By transforming back by the inverse operation of the discussion above, we can say that

  • for every integer \(k\) such that \(\max(P-A,R-B)\leq k\leq \min(Q-A,S-B)\), paint \((A+k,B+k)\) black.

We can similarly rephrase the second operation too:

  • for every integer \(k\) such that \(\max(1-A,B-N)\leq k\leq \min(N-A,B-1)\), paint \((A+k,B-k)\) black

can be replaced with

  • for every integer \(k\) such that \(\max(P-A,B-S)\leq k\leq \min(Q-A,B-R)\), paint \((A+k,B-k)\) black.

Now, we consider simulating these operations. Each operation is performed at most \(\min(Q-P+1,S-R+1)\) time, which is obviously at most \(3\times 10^5\). (Actually the evaluation can be stricter: we can say that it is no more than \([\sqrt{300000}]=547\).)

Therefore, this simulation can be done in the time limit, so the problem has been solved. In some programming languages like C++, if you store the range to be simulated with a fixed-size, it will need a size of \(300000\times 300000\), which will exceed the memory limit.

Another solution

In the explanation above, the first operation was rephrased as follows:

  • for every integer \(k\) such that \(1\leq A+k \leq N\) and \(1 \leq B+k \leq N\) , paint \((A+k,B+k)\) black.

This can be further reworded as:

  • for every pair of integers \((i,j)\) such that \(1\leq i \leq N\), \(1 \leq j \leq N\), and \(i-j=A-B\), paint \((i,j)\) black.

Similarly, the second operation is equivalent to:

  • for every pair of integers \((i,j)\) such that \(1\leq i \leq N\), \(1 \leq j \leq N\), and \(i+j=A+B\), paint \((i,j)\) black.

By using these facts, we may solve this problem in the following alternative way: for each \((i,j)\) such that \(P\leq i\leq Q\) and \(R\leq j\leq S\), check if \(i-j=A-B\) or \(i+j=A+B\), and if it holds, output #, or it doesn’t, output .. This simplifies the implementation a bit.

Sample code in C++:

#include <bits/stdc++.h>

using namespace std;

int main(void) {
	long long n, a, b;
	long long p, q, r, s;
	long long x, y;
	string str = "";
	vector<string>ans;

	cin >> n >> a >> b;
	cin >> p >> q >> r >> s;

	for (long long i = 0; i < (s - r + 1); i++)str += '.';
	for (long long i = 0; i < (q - p + 1); i++)ans.push_back(str);


	x = max(p - a, r - b);
	y = min(q - a, s - b);
	for (long long i = x; i <= y; i++)ans[a + i - p][b + i - r] = '#';

	x = max(p - a, b - s);
	y = min(q - a, b - r);
	for (long long i = x; i <= y; i++)ans[a + i - p][b - i - r] = '#';


	for (long long i = 0; i < (q - p + 1); i++)cout << ans[i] << endl;

	return 0;
}

Sample code of the alternative solution (C++):

#include <bits/stdc++.h>

using namespace std;

int main(void) {
	long long n, a, b;
	long long p, q, r, s;

	cin >> n >> a >> b;
	cin >> p >> q >> r >> s;

	for (long long i = p; i <= q; i++) {
		for (long long j = r; j <= s; j++) {
			if ((i - j) == (a - b))cout << '#';
			else if ((i + j) == (a + b))cout << '#';
			else cout << ".";
		}
		cout << endl;
	}

	return 0;
}

posted:
last update: