Simply simulate the process using pointers
381A - Sereja and Dima
We can simply simulate the process by using two pointers and initialize two variable to track the values for each player and every time choose the maximum between the values pointed by the two pointer and move that pointer to the opposite direction by one and use a boolean value to keep track of who's turn it is.
The time complexity is $$$O(n)$$$ with $$$O(1)$$$ space
n = int(input())
arr = list(map(int,input().split()))
s = 0
d = 0
l = 0
r = n - 1
turn = True
while l <= r:
if arr[l] > arr[r]:
val = arr[l]
l += 1
else:
val = arr[r]
r -= 1
if turn:
s += val
turn = False
else:
d += val
turn = True
print(s,d)
1789B - Serval and Inversion Magic
1789B - Serval and Inversion Magic
If $$$s$$$ is palindromic initially, we can operate on the interval [1,n], the answer is $$$"Yes"$$$.
Let's consider the other case. In a palindrome $$$s$$$, for each $$$i$$$ in $$$[1,⌊n/2⌋]$$$, $$${s_i} ={s_n−i+1}$$$ must hold. For those $$$i$$$, we may check whether $$${s_i} = {s_n−i+1}$$$ is true in the initial string. For all the illegal positions $$$i$$$, the operation must contain either $$$i$$$ or $$$n+1−i$$$, but not both. For the legal positions, the operation must contain neither of $$$i$$$ nor $$$n+1−i$$$, or both of them. If the illegal positions is continuous (which means that they are $$$l,l+1,…,r−1,r$$$ for some $$$l$$$ and $$$r$$$), we may operate on the interval $$$[l,r]$$$ (or $$$[n+1−r,n+1−l]$$$), making the string palindromic. The answer is Yes. Otherwise, there must be some legal positions that lie between the illegal ones. Suppose the illegal positions range between $$$[l,r]$$$ (but not continuous), and the operation is $$$[o1,o2]$$$.
Without loss of generality, let the operation lies in the left part of the string. Then $$$o1≤l,r≤o2<n+1−r$$$ must hold to correct all the illegal positions. This interval covers all the legal positions that lie between the illegal ones but does not cover their symmetrical positions. Thus, such kind of operation will produce new illegal positions. In other words, there are no valid operations in this situation. The answer is No.
The time complexity is $$$O(n)$$$ with $$$O(1)$$$ space
def main():
n = int(input())
arr = input()
l = 0
r = len(arr)-1
flag = False
while l < n//2:
if arr[l] == arr[r]:
l += 1
r -= 1
elif arr[l] != arr[r] and not flag:
while l < n//2 and arr[l] != arr[r]:
l += 1
r -= 1
flag = True
elif arr[l] != arr[r] and flag:
print("No")
return
print("Yes")
if __name__ == "__main__":
t = int(input())
for _ in range(t):
main()
Try to find which variant of the two pointers could fit this problem
Try to use the for-while combo to solve this problem
978C - Letters
Let's consider that if the first tower consists $$$n$$$ floors, so floor number $$$n+1$$$ belong to the next tower and it would be the first floor for that tower, by using this logic we can track if the current floor is found in the current tower or not. We can use the for while two-pointer variant, We iterate on the first array using for loop and the while loop will track how many of the floor numbers in the second array is in the current tower. for further understanding you can see the implementation below
The time complexity is $$$O(n)$$$ with $$$O(1)$$$ space
n,m = map(int,input().split())
arr1 = list(map(int,input().split()))
arr2 = list(map(int,input().split()))
r = 0
cur = 0
prev = 0
for i in range(len(arr1)):
cur += arr1[i]
while r < len(arr2) and arr2[r] <= cur:
print(i+1,arr2[r] - prev)
r += 1
prev = cur
Try sorting the array first
can we group the students using two pointers
1092B - Teams Forming
First Let's sort the array and try to group the students until the max difference not exceed $$$5$$$. Create two pointers to point to the first student in the group and move the other pointer until the difference exceeds $$$5$$$ and then we move the first pointer until the difference goes to being less than or equal to $$$5$$$ and do the process again. While we do the process we track the maximum number of student in one group and we return that as answer.
The time complexity is $$$O(nlog(n))$$$ with $$$O(1)$$$ space
n = int(input())
arr = list(map(int,input().split()))
arr.sort()
ans = 0
l = 0
r = 0
for i in range(len(arr)):
while r < len(arr) and arr[r] - arr[l] <= 5:
r += 1
ans = max(ans,r-l)
l += 1
print(ans)
Try to think this problem as a math problem
1656B - Subtract Operation
Let's understand it using this array $$$[a,b,c,d]$$$, First let's choose the $$$d$$$ so the array becomes $$$[a-d,b-d,c-d]$$$ so if we choose the $$$c-d$$$ next the array becomes $$$[a-c,b-c]$$$ since the $$$d$$$ is in both side they will cancel each other, and finally let's choose the $$$b-c$$$ so the array becomes $$$[a-b]$$$. if you look close the final element does only depend in two element of the array, So our task is to find those two value. We can use two pointer to find if there are two values in the array when subtract it gives us the value $$$k$$$.
The time complexity is $$$O(nlog(n))$$$ with $$$O(1)$$$ space
t = int(input())
for _ in range(t):
n,k = map(int,input().split())
arr = list(map(int,input().split()))
arr.sort()
l = 0
r = 1
flag = False
if n == 1:
if arr[0] == k:
print("YES")
else:
print("NO")
continue
while l < n and r < n:
if arr[l] + abs(k) == arr[r]:
flag = True
break
elif arr[l] + abs(k) < arr[r]:
l += 1
else:
r += 1
if flag:
print("YES")
else:
print("NO")