Educational Codeforces Round 53 Editorial

After I read the solution to the problem, I found that my solution was simply unsightly.

Solved 4 out of 7, and my solution to C was hacked, because of my incorrect order when i meet in the middle.

I wasted about 20 mins on problem A due to the incomprehensible description, at last i just find a harder solution and passed the pretests.

Neither have i read the questions calmly nor assigned time, that's why i got an unacceptable rank.

1073A - Diverse Substring

1073A - Diverse Substring

Notice that the string of two distinct letter is already diverse. That implies that the answer is "NO" if and only if all the letters in the string are the same. Otherwise you can check all pairs of adjacent letters in \(O(n)\)
Overall complexity: \(O(n)\)

n = int(input())
s = input()
for i in range(n - 1):
	if (s[i] != s[i + 1]):
		print("YES")
		print(s[i], s[i + 1], sep="")
		exit(0)
print("NO")

1073B - Vasya and Books

1073B - Vasya and Books

Let's maintain the pointer \(pos\) to the topmost non-deleted book and whether each book whether is removed from the stack or not. Initially, all books are in a stack, and \(pos\) is 0 (if we store the array 0-indexed). We will process the array \(B\) in the order \(b_1,b_2, \cdots, b_n\). If the current book \(b_i\) is removed from the stack, then the answer for it is zero. Otherwise, we will increment the pointer \(pos\) until the equality \(a_{pos} = b_i\) is satisfied, while marking all the intermediate books in the array \(u\). After that, the answer for the book
\(b_i\) will be the number of marked books in the \(u\) array (including itself).

Since the pointer \(pos\) shifts \(n\) times at total, we get a solution with an \(O(n)\) complexity.

#include <bits/stdc++.h>

using namespace std;

const int N = int(2e5) + 9;

int n, a[N], b[N];
bool u[N];

int main() {
	scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
    	scanf("%d", a + i);
    }
    for(int i = 0; i < n; ++i){
    	scanf("%d", b + i);
    }
	
	int pos = 0;
	for(int i = 0; i < n; ++i){
		int x = b[i];
		if(u[x]){
			printf("0 ");
			continue;
		}
		
		int cnt = 0;
		while(true){
			++cnt;
			u[a[pos]] = true;
			if(a[pos] == x) break;
			++pos;
		} 
		
		++pos;
		printf("%d ", cnt);
	}    
	
	puts("");
    return 0;
}

1073C - Vasya and Robot

1073C - Vasya and Robot

Denote \(d = |x| + |y|\). If \(d>n\), then the answer is -1, since the robot will not have the time to reach \((x, y)\) cell in \(n\) steps. Also, if \(d\) and \(n\) have different parity, then the answer is also -1, as in one move the robot changes the parity of the sum of its coordinates.

In all other cases, the answer exists. Let's use binary search to solve this problem. Consider all segments of length \(len\). For a fixed length of the segment \(len\), let's iterate over the position of the beginning of the segment \(l\). At the same time, we will maintain the cell that the robot will stop at if it execute all commands, except commands with indices \(l,l+1 \cdots,l+len−1\). We denote this position as \((x_0,y_0)\). We also calculate the distances from the cell \((x_0,y_0)\) to the cell \((x,y)\) — the value \(d_0=|x−x_0|+|y−y_0|\). If there is at least one position of the beginning of the segment for which \(d_0 \le len\) then we can change the segment of length \(len\) so that the robot comes to the \((x,y)\) cell, otherwise it can't.

const int maxn = 2e5 + 100;
int n, nx, ny, ans;
char str[maxn];
int lef[maxn], rgt[maxn], up[maxn], down[maxn];

int main() {
	while (~scanf("%d %s %d %d", &n, str + 1, &nx, &ny)) {
		seta(up, 0), seta(down, 0), seta(rgt, 0), seta(lef, 0);
		if (abs(nx) + abs(ny) > n || ((abs(nx) + abs(ny)) & 1) != (n & 1)) return printf("-1\n"), 0;
		for (int i = 1; i <= n; ++ i) {
			if (str[i] == 'R') rgt[i] ++;
			if (str[i] == 'U') up[i] ++;
			if (str[i] == 'D') down[i] ++;
			if (str[i] == 'L') lef[i] ++;
		}
		for (int i = 1; i <= n; ++ i) {
			up[i] += up[i - 1];
			rgt[i] += rgt[i - 1];
			down[i] += down[i - 1];
			lef[i] += lef[i - 1];
		}
		ans = 0x7fffffff;
		if (nx < 0) {
			for (int i = 1; i <= n; ++ i)
				swap(lef[i], rgt[i]);
			nx = -nx;
		}
		if (ny < 0) {
			for (int i = 1; i <= n; ++ i) {
				swap(up[i], down[i]);
			}
			ny = -ny;
		}
		if (rgt[n] - lef[n] == nx && up[n] - down[n] == ny)
			return printf("0\n"), 0;
		if (nx >= 0 && ny >= 0) {
			for (int i = 1; i <= n; ++ i) {
				int x1 = rgt[i - 1] - lef[i - 1];
				int y1 = up[i - 1] - down[i - 1];
				int l = i, r = n + 1;
				while (l < r) {
					int mid = (l + r) >> 1;
					int x2 = rgt[n] - rgt[mid] - (lef[n] - lef[mid]);
					int y2 = up[n] - up[mid] - (down[n] - down[mid]);
					if ((mid - i + 1) >= (abs(nx - (x1 + x2))  + abs(ny - (y1 + y2)))) ans = min(ans, (r = mid) - i + 1); else l = mid + 1;
				}
			}
		}
		cout << ans << endl;
	}
}
posted @ 2018-10-27 10:13  AlessandroChen  阅读(154)  评论(0编辑  收藏  举报