CCCGuide
Data Structures, Simulation and Ad-hoc (J2–J4)

Intro to Geometry

common

Some Junior problems describe points or tiles laid out in a plane and ask a question about where they are. They need little formal geometry. The work is reading the layout carefully and reducing it to something you can compare or count:

  1. Track the extremes — scan the points once, keeping the smallest and largest coordinates (Art).
  2. Count the contacts — what a tile contributes depends on which tiles it touches (Trianglane).

Art places drops of paint on a canvas using (x, y) coordinates: x grows to the right, y grows upward, and (0, 0) is the bottom-left corner. Trianglane has no coordinates, and its tiles are identified by row and column.

J3 Walkthrough: Art2020 · J3 · Original problem · DMOJ

Mahima has been experimenting with a new style of art. She stands in front of a canvas and, using her brush, flicks drops of paint onto the canvas. When she thinks she has created a masterpiece, she uses her 3D printer to print a frame to surround the canvas.

Your job is to help Mahima by determining the coordinates of the smallest possible rectangular frame such that each drop of paint lies inside the frame. Points on the frame are not considered inside the frame.

The first line of input contains the number of drops of paint, NN, where 2≤N≤1002 \le N \le 100 and NN is an integer. Each of the next NN lines contain exactly two positive integers XX and YY separated by one comma (no spaces). Each of these pairs of integers represents the coordinates of a drop of paint on the canvas. Assume that X<100X < 100 and Y<100Y< 100, and that there will be at least two distinct points. The coordinates (0,0)(0,0) represent the bottom-left corner of the canvas.

For 12 of the 15 available marks, XX and YY will both be two-digit integers.

Output two lines. Each line must contain exactly two non-negative integers separated by a single comma (no spaces). The first line represents the coordinates of the bottom-left corner of the rectangular frame. The second line represents the coordinates of the top-right corner of the rectangular frame.

5
44,62
34,69
24,78
42,44
64,10

Output for Sample Input

23,9
65,79

Explanation of Output for Sample Input

The bottom-left corner of the frame is (23,9)(23,9). Notice that if the bottom-left corner is moved up, the paint drop at (64,10)(64,10) will not be inside the frame. (See the diagram below.) If the corner is moved right, the paint drop at (24,78)(24,78) will not be inside the frame. If the corner is moved down or left, then the frame will be larger and no longer the smallest rectangle containing all the drops of paint. A similar argument can be made regarding the top-right corner of the frame.

Within the square with bottom-left corner at (0,0) and top-right corner at (100,100), there is a rectangle with bottom-left corner at (23,9) and top-right corner at (65,79). The inner rectangle just contains the five input points.

Solution

The picture in the statement only illustrates the sample, and the answer depends on four numbers: the smallest and largest X, and the smallest and largest Y. A rectangle containing every drop has to reach at least as far left as the leftmost drop, as far right as the rightmost, and likewise up and down, and the smallest such rectangle stops exactly there. Its bottom-left corner is built from the smallest X and Y, and its top-right corner from the largest X and Y. So read all N points, keep a running minimum and maximum of each coordinate, and print the two corners.

One sentence in the statement changes the answer: points on the frame are not considered inside. A rectangle built from the raw minima and maxima would have the extreme drops sitting on its edges, which is not allowed. The output must be integers, so the closest the frame can get is one unit away: subtract 1 from each minimum and add 1 to each maximum. The sample shows this. The drops span x from 24 to 64 and y from 10 to 78, and the expected output is (23,9) to (65,79). It also explains why the input coordinates are positive while the output only has to be non-negative: a drop at x = 1 puts the frame at x = 0.

Each input line has the form X,Y with no spaces. For 12 of the 15 marks, both coordinates are two-digit numbers. A solution that slices fixed character positions would pass those marks and fail the rest, while splitting on the comma and converting each half with int works for any width.

With at most 100 points and one comparison per coordinate, the running time is not a concern.

Implementation

n = int(input())

xs = []
ys = []
for _ in range(n):
    x, y = input().split(',')
    xs.append(int(x))
    ys.append(int(y))

print(min(xs) - 1, min(ys) - 1, sep=',')
print(max(xs) + 1, max(ys) + 1, sep=',')

J4 Walkthrough: Trianglane2023 · J4 · Original problem · DMOJ

Bocchi the Builder just finished constructing her latest project: a laneway consisting of two rows of white equilateral triangular tiles. However, at the last moment, disaster struck! She accidentally spilled black paint on some of the tiles. Now, some of the tiles are wet and the other tiles are dry. Bocchi must place warning tape around the perimeters of all wet areas. Can you help her determine how many metres of tape she needs?

The first triangular tile will point upwards. Each pair of adjacent tiles (that is, tiles that share a common side) will point in opposite directions. Each tile has a side length of 1 metre.

The first line of input will consist of one positive integer CC, representing the number of columns.

The next two lines will each consist of CC integers separated by spaces. Each integer represents the colour of a tile along the laneway, with 1 indicating that the tile is black (wet) and 0 indicating that the tile is white (dry).

The following table shows how the available 15 marks are distributed:

MarksDescriptionBound
3The laneway is not very long, black tiles are never adjacent and the second row is fully white.C≤2 000C \le 2\,000
3The laneway is not very long, black tiles may be adjacent and the second row is fully white.C≤2 000C \le 2\,000
5The laneway is not very long, black tiles may be adjacent and may appear in the second row.C≤2 000C \le 2\,000
4The laneway may be very long, black tiles may be adjacent and may appear in the second row.C≤200 000C \le 200\,000

Output a single integer representing the length of tape Bocchi needs, in metres.

5
1 0 1 0 1
0 0 0 0 0 

Output for Sample Input 1

9

Explanation of Output for Sample Input 1

The tiles are painted as follows, creating three wet areas. Bocchi will need 9 metres of warning tape as shown in yellow.

Two rows of five equilateral triangle tiles. In the top row, the tiles are pointing up, down, up, down, up. In the bottom row, the tiles are pointing down, up, down, up, down. Each tile pointing upward in the top row shares a side with a tile pointing downward in the bottom row. Each tile pointing upward in the top row is outlined in yellow.

7
0 0 1 1 0 1 0
0 0 1 0 1 0 0

Output for Sample Input 2

11

Explanation of Output for Sample Input 2

The tiles are painted as follows, creating three wet areas. Bocchi will need 5 metres of warning tape to surround one area and 3 metres of warning tape to surround each of the other two areas as shown in yellow.

Two rows of seven tiles arranged as in the previous input. The third and fourth tiles in the top row (pointing up then down) and the third tile in the bottom row (pointing down) form a trapezoidal area outlined in yellow. Also, the sixth tile in the top row and the fifth tile in the bottom row are each outlined in yellow.

Solution

Warning tape goes on every side of a wet tile that faces a dry tile or the outside, and a side shared by two wet tiles needs none. That turns the problem into counting sides instead of tracing the shape. Every wet tile has three sides, which gives 3 × (wet tiles) in total, but a side shared by two wet tiles has been counted twice and shouldn't be counted at all, so each shared side removes 2:

tape = 3 × (wet tiles) − 2 × (shared wet sides)

What remains is to decide which pairs of tiles share a side, and this is where the triangles matter. There are two kinds of pairs:

  1. Neighbours in the same row — consecutive tiles in a row point in opposite directions and always share a slanted side.
  2. The two tiles in the same column — these also point in opposite directions, but they share a side only when the top tile points up, because its flat base is then the flat top of the tile below. When the top tile points down, its flat side lies on the outer edge of the laneway and the two tiles touch only at a corner. The first tile points up and directions alternate, so the top tile points up in columns 1, 3, 5, and so on.

A column therefore contributes a shared side only if it is an odd-numbered column and both of its tiles are wet.

Check this against the samples. Sample 1 has three wet tiles and none of them touch, so the tape is 3 × 3 = 9. Sample 2 has five wet tiles and two shared sides, the top-row pair in columns 3 and 4 and the pair in column 3, so the tape is 3 × 5 − 2 × 2 = 11.

The samples will not catch the most common mistake. In both, the only column with two wet tiles is column 3, which is odd. A solution that subtracts for every column with two wet tiles passes both samples and fails others: with C = 2, top row 0 1 and bottom row 0 1, the two wet tiles touch only at a corner, so the answer is 6, not 4. When a counting formula passes the samples, test one case where the geometry differs, such as an even column here.

The mark split follows the formula term by term. The first subtask (no adjacent black tiles, second row white) needs only 3 × (wet tiles). The second adds the same-row neighbours, and the third adds the column pairs. The last 4 marks raise C to 200 000, which three linear passes handle without trouble.

Implementation

c = int(input())
top = [int(t) for t in input().split()]
bottom = [int(t) for t in input().split()]
rows = [top, bottom]

tape = 0
for row in rows:
    for i in range(c):
        if row[i] == 1:
            tape += 3

# sides shared by neighbouring wet tiles in the same row
for row in rows:
    for i in range(1, c):
        if row[i] == 1 and row[i - 1] == 1:
            tape -= 2

# sides shared between the rows: only where the top tile points up,
# which is every even index (index 0 is column 1)
for i in range(0, c, 2):
    if top[i] == 1 and bottom[i] == 1:
        tape -= 2

print(tape)

Summary

Both problems above boil down to a single careful scan. In Art, one pass through the coordinates picks out the four extremes, and one sentence in the statement — that drops on the frame don’t count as inside — shifts every answer by 1. In Trianglane, the perimeter formula is just counting each tile's sides and subtracting for shared ones, but getting the shared-side rule right for column pairs requires knowing which direction each tile points.

For geometry problems at this level, the geometry itself is rarely the bottleneck. The subtleties are almost always in the edge conditions.

On this page

Contributors