Bender Problem (Codeforces 28A)
Tags: Implement, implementation

Robot Bender decided to make Fray a birthday present. He drove n nails and numbered them from 1 to n in some order. Bender decided to make a picture using metal rods. The picture is a closed polyline, which vertices should be nails (in the given order). The segments of the polyline should be parallel to the coordinate axes. Polyline is allowed to have self-intersections. Bender can take a rod and fold it exactly once in any place to form an angle of 90 degrees. Then he can attach the place of the fold to some unoccupied nail and attach two ends of this rod to adjacent nails. A nail is considered unoccupied if there is no rod attached to it (neither by it's end nor the by the fold place). No rod could be used twice. It is not required to use all the rods.Help Bender to solve this difficult task.

Input: The first line contains two positive integers n and m (4 ≤ n ≤ 500, 2 ≤ m ≤ 500, n is even) — the amount of nails and the amount of rods. i-th of the following n lines contains a pair of integers, denoting the coordinates of the i-th nail. Nails should be connected in the same order as they are given in the input. The last line contains m integers — the lenghts of the rods. All coordinates do not exceed 104 by absolute value. Lengths of the rods are between 1 and 200 000. No rod can be used twice. It is guaranteed that all segments of the given polyline are parallel to coordinate axes. No three consecutive nails lie on the same line.

Output: If it is impossible to solve Bender's problem, output NO. Otherwise, output YES in the first line, and in the second line output n numbers — i-th of them should be the number of rod, which fold place is attached to the i-th nail, or -1, if there is no such rod.If there are multiple solutions, print any of them.


Sample Inputs:
4 2
0 0
0 2
2 2
2 0
4 4

6 3
0 0
1 0
1 1
2 1
2 2
0 2
3 2 3

6 3
0 0
1 0
1 1
2 1
2 2
0 2
2 2 3

Sample Outputs:
YES
1 -1 2 -1

YES
1 -1 2 -1 3 -1

NO

Solution (Python):
def d(p1, p2):
    return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])
(n, m) = map(int, input().split())
points = []
result = True
for i in range(n):
    (x, y) = map(int, input().split())
    points.append((x, y))
rods = list(map(int, input().split()))
answer = []
for i in range(0, n, 2):
    dist = d(points[i], points[i - 1]) + d(points[i], points[i + 1])
    try:
        id = rods.index(dist)
    except ValueError:
        result = False
        break
    answer.append(str(id + 1))
    answer.append('-1')
    rods[id] = -1
else:
    print('YES')
    print(' '.join(answer))
    result = True
if len(answer) == 0:
    answer.append('-1')
    points.append(points[0])
    for i in range(1, n + 1, 2):
        dist = d(points[i], points[i - 1]) + d(points[i], points[i + 1])
        try:
            id = rods.index(dist)
        except ValueError:
            result = False
            break
        answer.append(str(id + 1))
        answer.append('-1')
        rods[id] = -1
    else:
        print('YES')
        print(' '.join(answer[:-1]))
        result = True
if result is False:
    print('NO')

Solution (Python):
def d(p1, p2):
    return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])
(n, m) = map(int, input().split())
points = []
result = True
for i in range(n):
    (x, y) = map(int, input().split())
    points.append((x, y))
rods = list(map(int, input().split()))
answer = []
for i in range(0, n, 2):
    dist = d(points[i], points[i - 1]) + d(points[i], points[i + 1])
    try:
        id = rods.index(dist)
    except ValueError:
        result = False
        break
    answer.append(str(id + 1))
    answer.append('-1')
    rods[id] = -1
else:
    print('YES')
    print(' '.join(answer))
    result = True
if len(answer) == 0:
    answer.append('-1')
    points.append(points[0])
    for i in range(1, n + 1, 2):
        dist = d(points[i], points[i - 1]) + d(points[i], points[i + 1])
        try:
            id = rods.index(dist)
        except ValueError:
            result = False
            break
        answer.append(str(id + 1))
        answer.append('-1')
        rods[id] = -1
    else:
        print('YES')
        print(' '.join(answer[:-1]))
        result = True
if result is False:
    print('NO')

Solution (Python):
def main():
    (n, m) = map(int, input().split())
    nails = []
    for _ in range(n):
        nails.append(tuple(map(int, input().split())))
    rods = list(map(int, input().split()))
    (rods_count1, rods_count2) = ({}, {})
    for (i, rod) in enumerate(rods):
        if rod not in rods_count1:
            rods_count1[rod] = [i]
        else:
            rods_count1[rod].append(i)
        if rod not in rods_count2:
            rods_count2[rod] = [i]
        else:
            rods_count2[rod].append(i)
    ans = []
    for i in range(0, n, 2):
        if i < n - 2:
            rod_len = abs(nails[i][0] - nails[i + 2][0]) + abs(nails[i][1] - nails[i + 2][1])
        else:
            rod_len = abs(nails[i][0] - nails[0][0]) + abs(nails[i][1] - nails[0][1])
        if rod_len not in rods_count1:
            break
        else:
            ans.append(-1)
            ans.append(rods_count1[rod_len].pop() + 1)
            if not rods_count1[rod_len]:
                del rods_count1[rod_len]
    else:
        print('YES')
        print(' '.join(map(str, ans)))
        return
    last_nail = nails.pop()
    nails.insert(0, last_nail)
    ans = []
    for i in range(0, n, 2):
        if i < n - 2:
            rod_len = abs(nails[i][0] - nails[i + 2][0]) + abs(nails[i][1] - nails[i + 2][1])
        else:
            rod_len = abs(nails[i][0] - nails[0][0]) + abs(nails[i][1] - nails[0][1])
        if rod_len not in rods_count2:
            break
        else:
            ans.append(rods_count2[rod_len].pop() + 1)
            ans.append(-1)
            if not rods_count2[rod_len]:
                del rods_count2[rod_len]
    else:
        print('YES')
        print(' '.join(map(str, ans)))
        return
    print('NO')
if __name__ == '__main__':
    main()