Skip to content

Instantly share code, notes, and snippets.

@yosupo06
Last active December 16, 2023 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yosupo06/2c97d2f6188ddbdf21515592c5e45ada to your computer and use it in GitHub Desktop.
Save yosupo06/2c97d2f6188ddbdf21515592c5e45ada to your computer and use it in GitHub Desktop.
#include <exception>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <mutex>
#include <random>
#include <thread>
#include <vector>
void fhc_solve(auto solve,
int num_testcase,
int parallel = -1,
std::filesystem::path tmpoutdir = std::filesystem::path()) {
if (tmpoutdir.empty()) {
auto random_name =
("output-" + std::to_string(std::mt19937_64(std::random_device()())()));
tmpoutdir = std::filesystem::temp_directory_path() / random_name;
std::filesystem::create_directory(tmpoutdir);
}
if (parallel == -1) {
parallel = int(std::thread::hardware_concurrency());
}
std::cerr << "Start FHC solver: tmp = " << tmpoutdir
<< ", parallel = " << parallel << std::endl;
std::mutex in_mutex, out_mutex;
std::atomic_int next_case_id = 1;
auto output_path = [&](int case_id) {
return tmpoutdir / std::filesystem::path("case_" + std::to_string(case_id) + ".out");
};
auto solve_single = [&](int process_id) {
while (true) {
in_mutex.lock();
int case_id = next_case_id++;
if (case_id > num_testcase) {
in_mutex.unlock();
return;
}
{
std::lock_guard<std::mutex> lock(out_mutex);
std::cerr << "[#" << process_id << "] Start case: " << case_id
<< " / " << num_testcase << std::endl;
}
auto start = std::chrono::system_clock::now();
solve([&] { in_mutex.unlock(); },
[&](auto f) {
std::lock_guard<std::mutex> lock(out_mutex);
int orig_stdout = dup(fileno(stdout));
if (freopen(output_path(case_id).c_str(), "w", stdout) ==
nullptr) {
throw std::runtime_error("freopen failed");
}
std::cout << "Case #" << case_id << ": " << std::flush;
f();
dup2(orig_stdout, fileno(stdout));
close(orig_stdout);
});
auto end = std::chrono::system_clock::now();
{
std::lock_guard<std::mutex> lock(out_mutex);
auto consumed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();
std::cerr << "[#" << process_id << "] End case: " << case_id << " ("
<< consumed_ms << " ms)" << std::endl;
}
}
};
std::vector<std::thread> threads;
for (int i = 0; i < parallel; i++) {
threads.push_back(std::thread([&, i] { solve_single(i); }));
}
for (int i = 0; i < parallel; i++) {
threads[i].join();
}
for (int c = 1; c <= num_testcase; c++) {
std::ifstream input(output_path(c));
std::cout << input.rdbuf();
}
}
// ここまでライブラリ
using namespace std;
void solve(auto input_end, auto output) {
int s, d, k;
cin >> s >> d >> k;
input_end();
int buns = 2 * (s + d);
int patties = s + 2 * d;
output([&] {
if (buns < k + 1 || patties < k) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
}
cout << flush;
});
};
int main() {
int t;
cin >> t;
fhc_solve([&](auto i, auto o){ solve(i, o); }, t);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment