-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrectangle_processor.cpp
More file actions
95 lines (82 loc) · 3.12 KB
/
Copy pathrectangle_processor.cpp
File metadata and controls
95 lines (82 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//Author: Zlata Dovbyk
//Laboratory work 4. Variant 12
#include "rectangle_processor.h"
#include <iostream>
#include <algorithm>
namespace RectangleProcessor {
std::vector<Event> events;
const Point EMPTY_RANGE = {0, -1};
void read_input() {
int cx, cy, w, h;
while (std::cin >> cx >> cy >> w >> h) {
if (w <= 0 || h <= 0) {
break;
} else {
int x1 = cx - w / 2;
int x2 = cx + (w - w / 2);
int y1 = cy - h / 2;
int y2 = cy + (h - h / 2);
events.push_back({x1, y1, y2, +1}); //start covering at x1
events.push_back({x2 + 1, y1, y2, -1}); //stop covering after x2
}
}
std::sort(events.begin(), events.end());
}
void update_active_y(int current_x, size_t& event_index, ActiveY& active_y) {
while (event_index < events.size() && events[event_index].x == current_x) {
const auto& e = events[event_index];
for (int y = e.y1; y <= e.y2; ++y) {
active_y[y] += e.type;
if (active_y[y] == 0) {
active_y.erase(y); //clean up unused y
}
}
++event_index;
}
}
void update_max_coverage(int current_x, const ActiveY& active_y,
std::vector<Point>& max_points, int& max_coverage) {
for (const auto& y_entry : active_y) {
if (y_entry.second > 0) {
int value = y_entry.second;
Point point = {current_x, y_entry.first}; //current point coverage
if (value > max_coverage) {
max_coverage = value;
max_points.clear();
max_points.push_back(point);
} else if (value == max_coverage) {
max_points.push_back(point);
}
}
}
}
void process_scanline(int current_x, size_t& event_index, ActiveY& active_y,
std::vector<Point>& max_points, int& max_coverage) {
update_active_y(current_x, event_index, active_y);
update_max_coverage(current_x, active_y, max_points, max_coverage);
}
Point get_x_range() {
if (events.empty()) return EMPTY_RANGE;
return {events.front().x, events.back().x};
}
void output_result(const std::vector<Point>& points, int max_coverage) {
std::cout << "*****\n";
std::cout << points.size() << "\n";
std::cout << max_coverage << "\n";
for (const auto& p : points) {
std::cout << p.first << " " << p.second << "\n";
}
}
void process() {
read_input();
ActiveY active_y;
std::vector<Point> max_points;
int max_coverage = 0;
size_t event_index = 0;
auto [min_x, max_x] = get_x_range();
for (int current_x = min_x; current_x <= max_x; ++current_x) {
process_scanline(current_x, event_index, active_y, max_points, max_coverage);
}
output_result(max_points, max_coverage);
}
}