-
Notifications
You must be signed in to change notification settings - Fork 1
/
2003 J5-S3.cpp
134 lines (91 loc) · 3.3 KB
/
2003 J5-S3.cpp
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
2003 J5/S3 - Floor Plan
Difficulty: Easy
Problem Type: Graph Theory
To determine the area of each room, I will be using recursion.
Essentially, I drop the index of the first empty space I encounter in that room, afterwards from the square, I will check up, down, left, right for other squares and call the same function again.
In each call, I will increase the area of the room by 1 and change the value of the square to 'c', meaning counted. This way, I do not count the same square twice.
I then put area of each room into a multiset to allow duplicates, but to also make sure it's ordered since we must fill from greatest to least.
Afterwards, we just calculate how many rooms we can fill and how much is leftover.
*/
#include <iostream>
#include <vector>
#include <string>
#include <set>
std::vector<std::vector<char>> floor_plan; //Represents the actual floor plan
int rooms = 0; //Represents how many rooms can be filled
int flooring, r, c; //Input variables
int room_area = 0; //Area of a room, this number will be reset after calculating the area of a room
std::multiset<int> room_areas; //Multiset containing all room areas
//Find area of a room function
void find_area (int i, int j){
floor_plan[i][j] = 'c'; //Prevent duplicate counting
room_area++; //Add area
//Check UP
if (i - 1 >= 0 && floor_plan[i - 1][j] == '.'){
find_area (i - 1, j);
}
//Check Right
if (j + 1 < c && floor_plan[i][j + 1] == '.'){
find_area (i, j + 1);
}
//Check Down
if (i + 1 < r && floor_plan[i + 1][j] == '.'){
find_area (i + 1, j);
}
//Check Left
if (j - 1 > 0 && floor_plan[i][j - 1] == '.'){
find_area (i, j - 1);
}
}
int main(){
std::cin >> flooring >> r >> c;
//Fill in floor plan
for (int i = 0; i < r; i++){
std::string row;
std::cin >> row;
std::vector<char> floor (c);
for (int j = 0; j < c; j++){
floor[j] = row[j];
}
floor_plan.push_back(floor);
}
//Traverse floor plan, search for empty space indicating a room
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++){
//If a room is found
if (floor_plan[i][j] == '.'){
find_area (i, j); //Find area
room_areas.insert(room_area); //Add area to set
room_area = 0; //Reset area to prepare for the next room
}
}
}
//Determine how many rooms can be filled
while (true){
//Traverse multiset in reverse since it's ordered from least to greatest
for (auto it = room_areas.rbegin(); it != room_areas.rend(); it++){
flooring -= *it;
//Remember to include 0
if (flooring >= 0){
rooms++;
}
//If we run out of flooring early
else{
flooring += *it;
break;
}
}
break;
}
//Outputting our answer, very important that we follow format correctly, if there's 1 room we must print out "room", otherwise "rooms"
std::cout << rooms;
if (rooms > 1 || rooms == 0){
std::cout << " rooms, ";
}
else{
std::cout << " room, ";
}
std::cout << flooring << " square metre(s) left over";
return 0;
}