Moving Chips (Codeforces 1680E)
Tags: Greedy, bitmasks

You are given a board of size $$$2 \times n$$$ ($$$2$$$ rows, $$$n$$$ columns). Some cells of the board contain chips. The chip is represented as '*', and an empty space is represented as '.'. It is guaranteed that there is at least one chip on the board.In one move, you can choose any chip and move it to any adjacent (by side) cell of the board (if this cell is inside the board). It means that if the chip is in the first row, you can move it left, right or down (but it shouldn't leave the board). Same, if the chip is in the second row, you can move it left, right or up.If the chip moves to the cell with another chip, the chip in the destination cell disappears (i. e. our chip captures it).Your task is to calculate the minimum number of moves required to leave exactly one chip on the board.You have to answer $$$t$$$ independent test cases.

Input: The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 2 \cdot 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow.The first line of the test case contains one integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$) — the length of the board. The second line of the test case contains the string $$$s_1$$$ consisting of $$$n$$$ characters '*' (chip) and/or '.' (empty cell). The third line of the test case contains the string $$$s_2$$$ consisting of $$$n$$$ characters '*' (chip) and/or '.' (empty cell).Additional constraints on the input:  in each test case, there is at least one chip on a board;  the sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$ ($$$\sum n \le 2 \cdot 10^5$$$). 

Output: For each test case, print one integer — the minimum number of moves required to leave exactly one chip on the board.


Sample Inputs:
5
1
*
.
2
.*
**
3
*.*
.*.
4
**.*
**..
5
**...
...**

Sample Outputs:
0
2
3
5
5

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [list(input().rstrip()) for __ in range(2)]
    (left, right) = (-1, 0)
    for i in range(n):
        if g[0][i] == '*' or g[1][i] == '*':
            if left == -1:
                left = i
            right = i
    ret = 0
    f = [0] * (n + 1)
    mid = (left + right) // 2
    for i in range(right):
        if f[i]:
            if g[0][i + 1] == '.' and g[1][i + 1] == '.':
                f[i + 1] = 1
            ret += 1
            continue
        if g[0][i] == '*' and g[1][i] == '*' and (g[0][i + 1] == '.') and (g[1][i + 1] == '.'):
            f[i + 1] = 1
            ret += 2
            continue
        if g[0][i] == '*':
            if g[0][i + 1] == '.' and g[1][i] == '.':
                g[0][i + 1] = '*'
            ret += 1
        if g[1][i] == '*':
            if g[1][i + 1] == '.' and g[0][i] == '.':
                g[1][i + 1] = '*'
            ret += 1
    cnt = 0
    if g[0][right] == '*':
        cnt += 1
    if g[1][right] == '*':
        cnt += 1
    return ret + (1 if cnt == 2 else 0)
for __ in range(int(input())):
    print(solve())

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [list(input().rstrip()) for __ in range(2)]
    (left, right) = (-1, 0)
    for i in range(n):
        if g[0][i] == '*' or g[1][i] == '*':
            if left == -1:
                left = i
            right = i
    ret = 0
    f = [0] * (n + 1)
    mid = (left + right) // 2
    for i in range(right):
        if f[i]:
            if g[0][i + 1] == '.' and g[1][i + 1] == '.':
                f[i + 1] = 1
            ret += 1
            continue
        if g[0][i] == '*' and g[1][i] == '*' and (g[0][i + 1] == '.') and (g[1][i + 1] == '.'):
            f[i + 1] = 1
            ret += 2
            continue
        if g[0][i] == '*':
            if g[0][i + 1] == '.' and g[1][i] == '.':
                g[0][i + 1] = '*'
            ret += 1
        if g[1][i] == '*':
            if g[1][i + 1] == '.' and g[0][i] == '.':
                g[1][i + 1] = '*'
            ret += 1
    cnt = 0
    if g[0][right] == '*':
        cnt += 1
    if g[1][right] == '*':
        cnt += 1
    return ret + (1 if cnt == 2 else 0)
for __ in range(int(input())):
    print(solve())

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [list(input().rstrip()) for __ in range(2)]
    (left, right) = (-1, 0)
    for i in range(n):
        if g[0][i] == '*' or g[1][i] == '*':
            if left == -1:
                left = i
            right = i
    ret = 0
    f = [0] * (n + 1)
    mid = (left + right) // 2
    for i in range(right):
        if f[i]:
            if g[0][i + 1] == '.' and g[1][i + 1] == '.':
                f[i + 1] = 1
            ret += 1
            continue
        if g[0][i] == '*' and g[1][i] == '*' and (g[0][i + 1] == '.') and (g[1][i + 1] == '.'):
            f[i + 1] = 1
            ret += 2
            continue
        if g[0][i] == '*':
            if g[0][i + 1] == '.' and g[1][i] == '.':
                g[0][i + 1] = '*'
            ret += 1
        if g[1][i] == '*':
            if g[1][i + 1] == '.' and g[0][i] == '.':
                g[1][i + 1] = '*'
            ret += 1
    cnt = 0
    if g[0][right] == '*':
        cnt += 1
    if g[1][right] == '*':
        cnt += 1
    return ret + (1 if cnt == 2 else 0)
for __ in range(int(input())):
    print(solve())