-
Notifications
You must be signed in to change notification settings - Fork 0
/
1g-destroying-barracks.js
149 lines (113 loc) · 6.59 KB
/
1g-destroying-barracks.js
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
G. Разрушить казарму
Ограничение времени 1 секунда (фактическое использование на тестах – до 67ms)
Ограничение памяти 256Mb (фактическое использование на тестах – до 5.74Mb)
Ввод стандартный ввод или input.txt
Вывод стандартный вывод или output.txt
Вы играете в интересную стратегию. У вашего соперника остались всего одна казарма — здание, в котором постоянно появляются новые солдаты. Перед атакой у вас есть x солдат. За один раунд каждый солдат может убить одного из солдат противника или нанести 1 очко урона казарме (вычесть единицу здоровья у казармы). Изначально у вашего оппонента нет солдат. Тем не менее, его казарма имеет y единиц здоровья и производит p солдат за раунд.
Ход одного раунда:
1. Каждый солдат из вашей армии либо убивает одного из солдат вашего противника, либо наносит 1 очко урона казарме. Каждый солдат может выбрать своё действие. Когда казарма теряет все свои единицы здоровья, она разрушается.
2. Ваш противник атакует. Он убьет k ваших солдат, где k — количество оставшихся у противника солдат.
3. Если казармы еще не разрушены, ваш противник производит p новых солдат.
Ваша задача — разрушить казарму и убить всех солдат противника. Если это возможно, посчитайте минимальное количество раундов, которое вам нужно для этого. В противном случае выведите -1.
Формат ввода
На вход подаётся три целых числа x, y, p (1 ≤ x, y, p ≤ 5000) — количество ваших солдат на старте игры, количество очков здоровья казармы и количество производимых за раунд казармой солдат, соответственно. Каждое число расположено в новой строке.
Формат вывода
Если возможно убить всех вражеских солдат и разрушить казарму, выведите минимальное количество раундов, необходимых для этого. В противном случае выведите -1.
Пример 1
Ввод
10
11
15
Вывод
4
Пример 2
Ввод
1
2
1
Вывод
-1
Пример 3
Ввод
1
1
1
Вывод
1
Пример 4
Ввод
25
200
10
Вывод
13
Примечания
В первом примере в первом раунде сначала все ваши солдату атакуют казарму, после этого не происходит ничего, потому что у врага нет солдат, затем у врага появляется 15 солдат. Во втором раунде один ваш солдат добивает казарму, остальные 9 солдат убивают 9 солдат врага. Оставшиеся 6 солдат врага убивают 6 ваших солдат, но армия врага не пополняется, поскольку казарма разрушена. В третьем раунде сначала вы убиваете четверых солдат врага, затем враг двоих ваших солдат. В последнем, четвертом, раунде вы добиваете двух оставшихся солдат врага.
*/
const fs = require('fs');
const lines = fs.readFileSync('input.txt', 'utf8').toString().trim().split('\n');
const [ownSoldiersCount, barracksHealth, enemySoldiersRespawnRate] = lines.map((value) => parseInt(value));
let result = Infinity;
let ownSoldiersLeft = ownSoldiersCount;
let enemySoldiersLeft = 0;
let lastEnemySoldiersLeft = 0;
let barracksHealthLeft = barracksHealth;
let lastbarracksHealthLeft = barracksHealth;
let roundCount = 0;
function countAttackRounds(ownForces, enemyForces) {
let rounds = 0;
if (enemyForces <= 0) {
return 0;
}
while (ownForces > 0) {
++rounds;
enemyForces -= ownForces;
if (enemyForces <= 0) {
return rounds;
}
ownForces -= enemyForces;
}
return -1;
}
while (ownSoldiersLeft > 0) {
++roundCount;
let attackPower = ownSoldiersLeft;
if (barracksHealthLeft > 0 && barracksHealthLeft <= attackPower) {
const attackPowerAfterBarracksDestruction = attackPower - barracksHealthLeft;
const enemySoldiersLeftAfterBarracksDestruction = enemySoldiersLeft - attackPowerAfterBarracksDestruction;
const ownSoldiersLeftAfterBarracksDestruction = ownSoldiersLeft - enemySoldiersLeftAfterBarracksDestruction;
const roundsToKillEnemySoldiers = countAttackRounds(ownSoldiersLeftAfterBarracksDestruction, enemySoldiersLeftAfterBarracksDestruction);
if (roundsToKillEnemySoldiers !== -1) {
const newResult = roundCount + roundsToKillEnemySoldiers
result = Math.min(result, newResult);
}
}
if (enemySoldiersLeft >= attackPower) {
enemySoldiersLeft -= attackPower;
attackPower = 0;
} else {
attackPower -= enemySoldiersLeft;
enemySoldiersLeft = 0;
}
if (attackPower > 0) {
barracksHealthLeft -= attackPower;
}
ownSoldiersLeft -= enemySoldiersLeft;
if (barracksHealthLeft > 0) {
enemySoldiersLeft += enemySoldiersRespawnRate;
}
if (barracksHealthLeft <= 0 && enemySoldiersLeft <= 0) {
result = Math.min(result, roundCount);
break;
}
if (barracksHealthLeft === lastbarracksHealthLeft && enemySoldiersLeft === lastEnemySoldiersLeft) {
break;
}
lastbarracksHealthLeft = barracksHealthLeft;
lastEnemySoldiersLeft = enemySoldiersLeft;
}
if (result === Infinity) {
result = -1;
}
fs.writeFileSync('output.txt', `${result}`);