diff --git a/CMakeLists.txt b/CMakeLists.txt index a3a3388..1ba0088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,4 +22,5 @@ add_executable(Playground sudoku/main.cc take-most-space-element/main.cc walking-in-maze/main.cc - network-connection/main.cpp) + network-connection/main.cpp + eating-snake/main.cc) diff --git a/eating-snake/data.in b/eating-snake/data.in new file mode 100644 index 0000000..3a4f01d --- /dev/null +++ b/eating-snake/data.in @@ -0,0 +1,5 @@ +2 +3 +11 14 14 +3 +1 5 2 6 3 25 diff --git a/eating-snake/data2.in b/eating-snake/data2.in new file mode 100644 index 0000000..e2c3778 --- /dev/null +++ b/eating-snake/data2.in @@ -0,0 +1,5 @@ +2 +5 +13 31 33 39 42 +5 +1 7 2 10 3 24 4 48 5 50 diff --git a/eating-snake/data3.in b/eating-snake/data3.in new file mode 100644 index 0000000..2d571bd --- /dev/null +++ b/eating-snake/data3.in @@ -0,0 +1,21 @@ +10 +3 +29 46 67 +3 +1 15 2 34 3 114 +3 +1 120 2 168 3 224 +3 +1 65 2 132 3 293 +3 +1 79 2 192 3 474 +3 +1 24 2 64 3 562 +3 +1 396 2 458 3 595 +3 +1 44 2 317 3 592 +3 +1 138 2 145 3 572 +3 +1 602 2 726 3 831 diff --git a/eating-snake/data3.out b/eating-snake/data3.out new file mode 100644 index 0000000..9f30a3d --- /dev/null +++ b/eating-snake/data3.out @@ -0,0 +1,144 @@ +eating log: +(3, 67) +eating log: +(2, 46) +eating log: +(1, 29) +3 gonna to eat 1 +3 give up, cuz it will be eaten after ate that snake, new strongest snake 2 +3 +alter log: +1 2 3 +eating log: +(3, 114) +eating log: +(2, 34) +eating log: +(1, 15) +3 gonna to eat 1 +3 has ate 1 +eating log: +(3, 99) +eating log: +(2, 34) +3 gonna to eat 2 +3 has ate 2 +1 +alter log: +3 +eating log: +(3, 224) +eating log: +(2, 168) +eating log: +(3, 120) +3 gonna to eat 3 +3 give up, cuz it will be eaten after ate that snake, new strongest snake 2 +3 +alter log: +2 3 3 +eating log: +(3, 293) +eating log: +(3, 132) +eating log: +(2, 65) +3 gonna to eat 2 +3 has ate 2 +eating log: +(3, 228) +eating log: +(3, 132) +3 gonna to eat 3 +3 has ate 3 +1 +alter log: +3 +eating log: +(3, 474) +eating log: +(2, 192) +eating log: +(3, 79) +3 gonna to eat 3 +3 has ate 3 +eating log: +(3, 395) +eating log: +(2, 192) +3 gonna to eat 2 +3 has ate 2 +1 +alter log: +3 +eating log: +(3, 562) +eating log: +(2, 64) +eating log: +(3, 24) +3 gonna to eat 3 +3 has ate 3 +eating log: +(3, 538) +eating log: +(2, 64) +3 gonna to eat 2 +3 has ate 2 +1 +alter log: +3 +eating log: +(3, 595) +eating log: +(2, 458) +eating log: +(3, 396) +3 gonna to eat 3 +3 give up, cuz it will be eaten after ate that snake, new strongest snake 2 +3 +alter log: +2 3 3 +eating log: +(3, 592) +eating log: +(3, 317) +eating log: +(2, 44) +3 gonna to eat 2 +3 has ate 2 +eating log: +(3, 548) +eating log: +(3, 317) +3 gonna to eat 3 +3 has ate 3 +1 +alter log: +3 +eating log: +(3, 572) +eating log: +(2, 145) +eating log: +(3, 138) +3 gonna to eat 3 +3 has ate 3 +eating log: +(3, 434) +eating log: +(2, 145) +3 gonna to eat 2 +3 has ate 2 +1 +alter log: +3 +eating log: +(3, 831) +eating log: +(2, 726) +eating log: +(3, 602) +3 gonna to eat 3 +3 give up, cuz it will be eaten after ate that snake, new strongest snake 2 +3 diff --git a/eating-snake/main.cc b/eating-snake/main.cc new file mode 100644 index 0000000..3a49cba --- /dev/null +++ b/eating-snake/main.cc @@ -0,0 +1,142 @@ +#include +#include +#include + +using namespace std; + +//#define ENABLE_LOG + +struct snake { + int id; + int power; + + snake(int id, int power) { + this->id = id; + this->power = power; + } + + bool operator<(const snake &obj) const { + if (obj.power == power) return obj.id < id; + return obj.power < power; + } + + bool operator>=(const snake &obj) const { + return power >= obj.power; + } +}; + +bool sort_by_id(snake a, snake b) { + return b.id > a.id; +} + +void eat(vector &vec, bool skip_sort = false) { + if (vec.size() < 2) return; + if (!skip_sort) { + sort(vec.begin(), vec.end()); + } + +#if defined(ENABLE_LOG) + for (auto item: vec) { + printf("eating log: \n"); + printf("(%d, %d)\n", item.id, item.power); + } +#endif + + if (!(vec[0] >= vec[vec.size() - 1])) { + return; + } + + // If this snake ate the last snake + snake curr = vec[0]; + snake last = vec[vec.size() - 1]; +#if defined(ENABLE_LOG) + printf("%d gonna to eat %d\n", curr.id, last.id); +#endif + vec.pop_back(); + vec[0].power -= last.power; + sort(vec.begin(), vec.end()); + if (vec[0].id != curr.id) { + bool will_be_eaten = false; + int strongest_curr_power = vec[0].power; + // Looking up if current snake will be eaten + for (auto it = vec.rbegin(); it < vec.rend(); it++) { + if (strongest_curr_power >= it->power) { + if (it->id == curr.id) { + // So bad, the new strongest snake will eat the current strongest snake + // Give up eating right now! + will_be_eaten = true; + break; + } + // No more thinking, just go for it + strongest_curr_power -= it->power; + } + } + + if (will_be_eaten) { +#if defined(ENABLE_LOG) + printf("%d give up, cuz it will be eaten after ate that snake, new strongest snake %d\n", curr.id, + vec[0].id); +#endif + // It means the current snake going to be eaten + // Revert the action + for (auto &item: vec) { + if (item.id == curr.id) { + item.power = curr.power; + break; + } + } + vec.push_back(last); + return; + } + } + +#if defined(ENABLE_LOG) + printf("%d has ate %d\n", curr.id, last.id); +#endif + // Else, it means the current snake is still strong enough + // Going to see other snakes can be eaten... + return eat(vec, skip_sort = true); +} + +int main() { + int count; + cin >> count; + + vector snakes; + int t; + cin >> t; + for (int i = 0; i < t; i++) { + int a; + cin >> a; + snakes.emplace_back(i + 1, a); + } + + eat(snakes); + cout << snakes.size() << endl; + + for (int i = 0; i < count - 1; i++) { + int n; + cin >> n; + sort(snakes.begin(), snakes.end(), sort_by_id); +#if defined(ENABLE_LOG) + printf("alter log: \n"); + for (const auto &item: snakes) { + printf("%d ", item.id); + } + printf("\n"); +#endif + for (int j = 0; j < n; j++) { + int id, alter; + cin >> id >> alter; + if (snakes.size() < id) { + // Respawn + snakes.emplace_back(id, alter); + } else { + // Alter power + snakes[id - 1].power = alter; + } + } + eat(snakes); + cout << snakes.size() << endl; + } +} \ No newline at end of file