CodeForces Round 619 (Rated for Div. 2) Pariticipation report
Date: Feb. 13. 2020
CodeForces Round 619 (Rated for Div. 2) Pariticipation report
Since 2019-nCov is still impacting the society.
Taking part in such a competition might be a good choice.
Generally speaking, this round is not so hard.
Let me show the problems:
A. Three Strings
You are given three strings a, b and c of the same length n. For the same index order, you must swap the character in c with the character in either a or b. The problem is if it is possible that after these swaps the string a becomes exactly the same as the string b.
SAMPLE INPUT
4
aaa
bbb
ccc
abc
bca
bca
aabb
bbaa
baba
imi
mii
iim
SAMPLE OUTPUT
NO
YES
YES
NO
To solve it, just compare every character in c to those in a and b for the same index. If all of the character for the same index in a or b is same to c, the answer is YES
.
MY CODE
# python3
t = int(input())
for ti in range(t):
a = input()
b = input()
c = input()
f = 1
for i in range(len(a)):
if c[i] in (a[i],b[i]):
pass
else:
print('NO')
f = 0
break
if f:
print('YES')
B. Motarack's Birthday
You are given an non-negetive array a with some missing elements marked as -1
.Try to fill out of all missing elements with the same integer k to make the maximum absolute difference m between all adjacent elements minimized. Output the m and the k.
SAMPLE INPUT
7
5
-1 10 -1 12 -1
5
-1 40 35 -1 35
6
-1 -1 9 -1 3 -1
2
-1 -1
2
0 -1
4
1 -1 3 -1
7
1 -1 7 5 2 -1 5
SAMPLE OUTPUT
1 11
5 35
3 6
0 42
0 0
1 2
3 4
After thinking for about 20 minutes, I find the problem is asking the median
of the maximum value and the minimum value.
MY CODE
t = int(input())
for ti in range(t):
n = int(input())
li = [int(i) for i in input().split(' ')]
ss = 0
cc = 0
sep = 0
_min = 1919810114514
_max = 0
for idx, i in enumerate(li):
if i == -1:
if idx and li[idx-1] != -1:
_min = min(_min, li[idx-1])
_max = max(_max, li[idx-1])
else:
if idx and li[idx-1] != -1:
sep = max(sep, abs(li[idx-1]-i))
elif idx and li[idx-1] == -1:
_min = min(_min, i)
_max = max(_max, i)
ss += i
cc += 1
if cc:
# r = round(ss/cc)
r = (_min+_max)//2
sep = max(sep,r - _min, _max-r)
print(sep,r)
else:
print(0,0)
C. Ayoub's function
You are given a binary string (a string which contains only symbols "0" and "1") s. Define function f(s) is equal to the number of substring in s that contains at least one symbol of "1".
Now you know the count of "1" in every s. How will you construct s so the f(s) reach the max possible value? Output the maximum value.
SAMPLE INPUT
5
3 1
3 2
3 3
4 0
5 2
SAMPLE OUTPUT
4
5
6
0
12
Since we are finding a construction of s that makes the count of intervals contain "1" as large as possible. We can find that the f(s) is also equal to the total count of substrings in s subtract by the count of intervals contain all "0".
So we just need to make the length of every continuously "0" strings as small as possible.
MY CODE
def getarrsum(n):
return (1+n)*n//2
t = int(input())
for ti in range(t):
n, ctr = (int(i) for i in input().split(' '))
if n == ctr:
print((1+n)*n//2)
elif ctr:
tot = (1+n)*n//2
c0 = n - ctr
dvd = c0 // (1+ctr)
rem = c0 % (1+ctr)
cur = ctr+1 - rem
d1 = cur * getarrsum(dvd)
d2 = rem * getarrsum(dvd+1)
print(tot-d1-d2)
else:
print(0)
D. Time to Run
You are given a map contain n rows and m columns like this:
Every path between adjacent cells can be visited at most once. You start at the top-left cell in the grid. If you can move exactly k times, print your route. Otherwise print NO
.
SAMPLE INPUT
3 3 8
SAMPLE OUTPUT
YES
8
3 R
3 L
1 D
3 R
1 D
1 U
3 L
1 D
To visit all of the path, you can move like this:
So all we need is to count the moves and check if it can reach k.
CODE COPIED FROM STD
n,m,k= (int(i) for i in input().split(' '))
path = []
tot = 0
for i in range(n):
path.append((m-1,'R'))
tot += path[-1][0] * len(path[-1][1])
if i == 0:
path.append((m-1,'L'))
else:
path.append((m-1,'UDL'))
tot += path[-1][0] * len(path[-1][1])
if i == n-1:
path.append((n-1,'U'))
else:
path.append((1,'D'))
tot += path[-1][0] * len(path[-1][1])
if k > 4*n*m-2*n-2*m:
print('NO')
else:
while tot > k:
tmp = path[-1][1]
cur = path[-1][0] * len(tmp)
path.pop()
tot -= cur
if tot >= k:
continue
cur = k - tot
if cur // len(tmp) > 0:
path.append((cur//len(tmp),tmp))
tmp = tmp[:cur%len(tmp)]
if len(tmp) > 0:
path.append((1,tmp))
tot = k
print('YES')
p2 = []
for i in path:
if i[0]:
p2.append(i)
print(len(p2))
for i,j in p2:
if i:
print(i,j)
E. Nanosoft
You are given a picture colored by at most 4 colors: green (the symbol G
), red (the symbol R
), yellow (the symbol Y
) and blue (the symbol B
).
We define a picture logo
like this:
Can you cut the largest logo
from the given picture? Print the size of your logo
.
SAMPLE INPUT
5 5 5
RRGGB
RRGGY
YYBBG
YYBBR
RBBRG
1 1 5 5
2 2 5 5
2 2 3 3
1 1 3 5
4 4 5 5
SAMPLE OUTPUT
16
4
4
4
0
I didn't solve this problem actually, here is the official solution:
For each cell, we will calculate the maximum size of a Nanosoft logo in which it is the bottom right cell, in the top left square.
The cell marked with x in this picture:
If we had a grid like this:
If we take the cell in the second row, second column, it can make a Nanosoft logo with size 4×4, being the bottom right cell in the top left square.
We can calculate the answer for every cell using binary search , and checking every sub-square using 2D cumulative sum.
Now we build a 2D array that contains that previous calculated answer, lets call it val[n][m].
For the previous picture val will be like this:
Now for each query we can do binary search on its answer. We check the current mid this way:
The mid will tell us the length of one of the sides divided by 2.
Like if mid = 2, the area of the square we are checking is (4⋅4=16).
Now we should check the maximum element in the 2D array val, in the 2D range: (r1+mid−1,c1+mid−1,r2−mid,c2−mid).
The current mid is correct if the maximum element in that 2D range is greater than or equal to (4⋅mid⋅mid).
We can get the maximum value in a 2D range using 2D sparse table, with build in O(n⋅m⋅logn⋅logm) and query in O(1).
total Complexity is O(n⋅m⋅logn⋅logm+q⋅logm).
But actually it can be tolerate Complexity O(n^3) for the preprocess. That means we are not forced to use binary search.
After the preprocess, each query can be handled in O(1).
STD
#include <bits/stdc++.h>
using namespace std;
#define oo 1000000010
#define mod 1000000007
const int N = 510 , LOG = 10;
char grid[N][N];
int val[N][N] , sum[N][N][4];
int st[N][N][LOG][LOG] , lg[N];
int n , q , m , r1 , c1 , r2, c2 , nr , nc;
string S = "RGYB";
int dr[4] = {0 , 0 , 1 , 1};
int dc[4] = {0 , 1 , 0 , 1};
inline bool check(int r1,int c1,int r2,int c2,int k){
r1++,c1++,r2++,c2++;
return ((sum[r2][c2][k] - sum[r1 - 1][c2][k] - sum[r2][c1 - 1][k] + sum[r1 - 1][c1 - 1][k]) == (r2 - r1 + 1) * (c2 - c1 + 1));
}
inline bool can(int r,int c,int s){
if(r < 0 || c < 0) return false;
if(r + (s << 1) - 1 >= n || c + (s << 1) - 1 >= m) return false;
for(int i =0 ;i < 4;i++){
nr = r + dr[i] * s ;
nc = c + dc[i] * s;
if(!check(nr , nc , nr + s - 1 , nc + s - 1 , i))
return false;
}
return true;
}
void build(){
lg[1] = 0;
for(int i = 2;i<N;i++){
lg[i] = lg[i - 1];
if((1 << (lg[i] + 1)) == i)
lg[i]++;
}
for(int k = 1;k < LOG;k++){
for(int i=0;i + (1 << k) <= n;i++){
for(int j=0;j<m;j++){
st[i][j][k][0] = max(st[i][j][k - 1][0] , st[i + (1 << (k - 1))][j][k - 1][0]);
}
}
}
for(int l = 1;l < LOG;l++){
for(int k = 0;k < LOG;k++){
for(int i=0;i+(1 << k) <= n;i++){
for(int j = 0;j + (1 << l) <= m;j++){
st[i][j][k][l] = max(st[i][j][k][l - 1] , st[i][j + (1 << (l - 1))][k][l-1]);
}
}
}
}
}
int a , b;
inline int getmax(int r1,int c1,int r2,int c2){
if(r2 < r1 || c2 < c1 || r1 < 0 || r2 >= n || c1 < 0 || c2 >= m) return -oo;
a = lg[(r2 - r1) + 1];
b = lg[(c2 - c1) + 1];
return max(max(st[r1][c1][a][b] , st[r2 - (1 << a) + 1][c1][a][b]) , max(st[r1][c2 - (1 << b) + 1][a][b] , st[r2 - (1 << a) + 1][c2 - (1 << b) + 1][a][b]));
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=0;i<n;i++){
scanf(" %s",grid[i]);
for(int j=0;j<m;j++){
for(int k=0;k<4;k++){
sum[i + 1][j + 1][k] = sum[i][j + 1][k] + sum[i + 1][j][k] - sum[i][j][k] + (S[k] == grid[i][j]);
}
}
}
int low , high , mid , res;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
low = 1 , high = min(min(i + 1,n - i) , min(j + 1,m - j));
while(high >= low){
mid = ((low + high) >> 1);
if(can(i - mid + 1,j - mid + 1,mid))
st[i][j][0][0] = mid, low = mid + 1;
else
high = mid - 1;
}
}
}
build();
while(q--){
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
r1--,c1--,r2--,c2--;
low = 1 , high = (n >> 1) , res = 0;
while(high >= low){
mid = ((low + high) >> 1);
if(getmax(r1 + mid - 1,c1 + mid - 1,r2 - mid , c2 - mid) >= mid)
res = mid, low = mid + 1;
else
high = mid - 1;
}
printf("%d\n",res * res * 4);
}
return 0;
}
F. Super Jaber
You are given a n rows m columns grids colored by k (k<=40) colors. Every second you can move to adjacent cells or to a cell have the same color as you are standing on. Question is the least time consumption from cell (r1,c1) to cell (r2,c2).
SAMPLE INPUT
3 4 5
1 2 1 3
4 4 5 5
1 2 1 3
2
1 1 3 4
2 2 2 2
SAMPLE OUTPUT
2
0
At first I tend to use double source BFS, but unfortunately timed out.
Having discussed in ACM groups, they show me a solution to preprocess the map in time Complexity O(nmk) and memory Complexity O(nmk). Then for every query, solve it in O(k).
Preprocess the grids like this:
For every cell, calculate the nearest distance of color from 1 to k from it. So for every cell and every color, we have the nearest path saved in array dist. This can be done by multi-source BFS.
Then for every query, we can choose a best color to jump or just normally go to the endpoint without using the same color jump. So initialize the answer to Manhattan distance, literate c from 1 to k, the answer is exactly min(answer,dist[r2][c2][c],dist[r1][c1][c]).
I was worried about this solution as it seems to use same color jump only once. But I found this is not a mistake since every same color jump is done at the BFS.
I have tried to rewrite the solution in Python3, but though I used ctypes library it is too slow to solve the problem.
MY CODE
# coding:utf-8
from ctypes import *
dr = (0, 1, 0, -1)
dc = (1, 0, -1, 0)
# cost = [[0 for i in range(1000000)] for i in range(40)]
cost = (c_int8 * (1000000) * 40)()
class que():
def __init__(self):
self.mem = (c_int32 * 1000000)()
self.l = 0
self.r = 0
self.M = 1000000
def push(self,ar):
if self.r >= self.M:
self.r -= self.M
self.mem[self.r] = ar
self.r += 1
def pop(self):
if self.l >= self.M:
self.l -= self.M
self.l += 1
return self.mem[self.l-1]
def anything(self):
return self.r != self.l
def clear(self):
self.l = 0
self.r = 0
q = que()
n, m, k = (int(i) for i in input().split(' '))
grid = []
cells = [[] for i in range(k)]
def bfs(col):
q.clear()
for kk in cells[col]:
cost[col][kk] = -1
q.push(kk)
done = (c_bool * k)()
while q.anything():
now = q.pop()
nx = now // m
ny = now - nx * m
now_col = grid[now]
if not done[now_col]:
done[now_col] = 1
for kk in cells[now_col]:
if 0 == cost[col][kk]:
cost[col][kk] = max(0,cost[col][now]) + 1
q.push(kk)
for i in range(4):
cx,cy = nx+dr[i], ny+dc[i]
cur = cx*m+cy
if cx >= 0 and cx < n and \
cy >= 0 and cy < m and \
0 == cost[col][cur]:
cost[col][cur] = max(0,cost[col][now]) + 1
q.push(cur)
for i in range(n):
tmp = [int(j)-1 for j in input().split(' ')]
grid += tmp
for jd, j in enumerate(tmp):
cells[j].append(i*m+jd)
for co in range(k):
bfs(co)
t = int(input())
for ti in range(t):
x,y,X,Y = (int(i)-1 for i in input().split(' '))
ans = abs(x-X) + abs(y-Y)
for i in range(k):
if cost[i][x*m+y] == -1:
cost[i][x*m+y] = 0
if cost[i][X*m+Y] == -1:
cost[i][X*m+Y] = 0
ans = min(ans, 1 + cost[i][x*m+y] + cost[i][X*m+Y])
print(ans)
STD
#include <bits/stdc++.h>
using namespace std;
#define oo 1000000000
#define mod 998244353
const int N = 1010 , K = 45;
int n , m , k , r1 , r2 , c1 , c2 , grid[N][N] , ans = 0;
int cost[K][N][N];
bool done[K];
queue < pair<int,int> > q;
int dr[4] = {0 , 1 , 0 , -1};
int dc[4] = {1 , 0 ,-1 , 0};
vector < pair<int,int> > cells[K];
void BFS(int col){
for(int i = 0; i < (int)cells[col].size();i++){
cost[col][cells[col][i].first][cells[col][i].second] = 0;
q.push(make_pair(cells[col][i].first,cells[col][i].second));
}
for(int i = 1;i <= k;i++) done[i] = false;
int r , c , nr , nc;
while(!q.empty()){
r = q.front().first;
c = q.front().second;
q.pop();
if(!done[grid[r][c]]){
done[grid[r][c]] = true;
for(int i = 0 ; i < (int)cells[grid[r][c]].size() ;i++){
nr = cells[grid[r][c]][i].first;
nc = cells[grid[r][c]][i].second;
if(cost[col][nr][nc] == -1){
cost[col][nr][nc] = cost[col][r][c] + 1;
q.push(make_pair(nr , nc));
}
}
}
for(int i = 0 ;i < 4;i++){
nr = r + dr[i];
nc = c + dc[i];
if(nr >= 0 && nr < n && nc >= 0 && nc < m && cost[col][nr][nc] == -1){
cost[col][nr][nc] = cost[col][r][c] + 1;
q.push(make_pair(nr , nc));
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i = 0 ;i < n;i++){
for(int j = 0 ;j < m;j++){
scanf("%d",&grid[i][j]);
cells[grid[i][j]].push_back(make_pair(i , j));
}
}
memset(cost, -1, sizeof(cost));
for(int i = 1;i <= k;i++)
BFS(i);
int q;
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
r1--,c1--,r2--,c2--;
ans = abs(r1 - r2) + abs(c1 - c2);
for(int i = 1;i <= k;i++)
ans = min(ans , 1 + cost[i][r1][c1] + cost[i][r2][c2]);
printf("%d\n",ans);
}
return 0;
}
嘛,为了应付英语日记写成了英语