-
Notifications
You must be signed in to change notification settings - Fork 13
/
the-helpdesk.cpp
123 lines (103 loc) · 3.57 KB
/
the-helpdesk.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
#include <bits/stdc++.h>
struct Visitor { int helptime; Visitor(int helptime = 0): helptime{ helptime }{} };
struct Counter {
typedef enum { AVAILABLE, BUSY, BREAK } STATUS;
Counter(int id = 0, float efficiency = 0.f, float worktime = 0.f):
id{ id }, efficiency{ efficiency }, wTime{ worktime } {}
STATUS advance(float time) {
curTime += time;
switch(status) {
case AVAILABLE: return AVAILABLE;
case BUSY: {
consecwTime += time;
wLoad = std::max(0.f, wLoad - time);
if ( wLoad > 0.f ) return BUSY;
if ( consecwTime >= wTime ) {
status = BREAK;
consecwTime = 0;
wLoad = 10;
lastBreakT = curTime;
breaks++;
}
else {
status = AVAILABLE;
wLoad = 0;
}
} break;
case BREAK: {
wLoad = std::max(0.f, wLoad - time);
if ( wLoad > 0.f ) return BREAK;
status = AVAILABLE, wLoad = 0.f;
} break;
}
return AVAILABLE;
}
[[maybe_unused]] bool assign(Visitor vis) {
if ( AVAILABLE != status )
return false;
status = BUSY;
wLoad = vis.helptime / efficiency;
clients++;
return true;
}
float nextStep(void) const { return wLoad; }
int id{ 0 };
STATUS status{ AVAILABLE };
float efficiency{ 1.f }, consecwTime{ 0.f }, wTime{ 0.f }, wLoad{ 0.f };
float curTime{ 0.f }, lastBreakT{ 0.f};
int clients{ 0 }, breaks{ 0 };
};
int main() {
int worktime, nc, nv, helptime;
float efficiency;
std::cin >> worktime >> nc; std::cin.ignore();
std::deque<Visitor> queue;
std::vector<Counter> counters(nc);
int id{ 0 };
for (auto& ct : counters) {
std::cin >> efficiency; std::cin.ignore();
ct = Counter(++id, efficiency, worktime);
}
std::cin >> nv; std::cin.ignore();
for (int i = 0; i < nv; i++) {
std::cin >> helptime; std::cin.ignore();
queue.push_back(helptime);
}
Counter* curCounter{ nullptr };
const auto& getStep{ [&](){
float stepT{ std::numeric_limits<float>::max() };
for ( const auto& ct : counters ) {
if ( auto nxt{ ct.nextStep() }; nxt < stepT ) {
stepT = nxt;
}
}
return stepT;
} };
const auto& advance{ [&](float stepT){
curCounter = nullptr;
for ( auto& ct : counters )
if ( (Counter::STATUS::AVAILABLE == ct.advance(stepT)) && (nullptr == curCounter) )
curCounter = &ct;
} };
const auto& processVisitor{ [&]() {
if ( nullptr == curCounter ) return;
if ( curCounter->assign(queue.front()) )
queue.pop_front();
} };
float curTime{ 0.f }, stepTime{ 0.f };
while ( !std::empty(queue) ) {
stepTime = getStep();
curTime += stepTime;
advance(getStep());
processVisitor();
}
for ( int i{ 0 }; i < std::size(counters); ++i )
if ( counters[i].lastBreakT == curTime )
counters[i].breaks--;
for ( int i{ 0 }; i < std::size(counters); ++i )
std::cout << ( (0 != i) ? " " : "" ) << counters[i].clients;
std::cout << std::endl;
for ( int i{ 0 }; i < std::size(counters); ++i )
std::cout << ( (0 != i) ? " " : "" ) << counters[i].breaks;
std::cout << std::endl;
}