Submission #1256220

#TimeUsernameProblemLanguageResultExecution timeMemory
1256220biankCOVID tests (CEOI24_covid)C++20
100 / 100
2354 ms15768 KiB
#include "bits/stdc++.h" using namespace std; #define forsn(i, s, n) for (int i = int(s); i < int(n); i++) #define forn(i, n) forsn(i, 0, n) #define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--) #define dforn(i, n) dforsn(i, 0, n) #define sz(x) int(x.size()) #define all(x) begin(x), end(x) using ll = long long; using ld = long double; using vi = vector<int>; using vb = vector<bool>; using vll = vector<ll>; using ii = pair<int, int>; using iii = tuple<int, int, int>; const int MAX_N = 1005; /// You may use: // The number of students int n; // The probability any given student is positive double P; // This function performs a test on a subset of samples. // Its argument is a vector of Booleans of length N, // where the i-th element is true if the i-th sample should be added to the mix. // It returns true if (and only if) at least one of the samples in the mix is positive. ld dp[MAX_N][MAX_N]; int best[MAX_N][MAX_N]; bool test_students(vb mask) { assert(mask.size() == (size_t)n); std::string mask_str(n, ' '); for (int i = 0; i < n; i++) mask_str[i] = mask[i] ? '1' : '0'; printf("Q %s\n", mask_str.c_str()); fflush(stdout); char answer; scanf(" %c", &answer); return (answer == 'P'); } map<ii, bool> memo; bool query(int l, int r) { if (r - l == 0) return false; if (memo.count(ii{l, r})) return memo[{l, r}]; vb curr(n, false); forsn(i, l, r) curr[i] = true; return memo[ii{l, r}] = test_students(curr); } vb ret; const ld INF = 1e9; void calcDP() { if (P == 0) return; vector<ld> pot(n + 1); pot[0] = 1; forsn(i, 1, n + 1) pot[i] = pot[i - 1] * (1 - P); dforn(i, n) { forsn(j, i + 1, n + 1) { if (j - i == 1) dp[i][j] = dp[j][j]; else { dp[i][j] = INF; forsn(k, 1, j - i) { ld prob = (1 - pot[k]) / (1 - pot[j - i]); ld curr = prob * dp[i][i + k] + (1 - prob) * dp[i + k][j] + 1; if (dp[i][j] > curr) dp[i][j] = curr, best[i][j] = k; } } } dp[i][i] = INF; forsn(k, 1, n - i + 1) { ld curr = (1 - pot[k]) * dp[i][i + k] + pot[k] * dp[i + k][i + k] + 1; if (dp[i][i] > curr) dp[i][i] = curr, best[i][i] = k; } } } void solve(int i, int j) { if (i == n) return; if (j - i == 1) { ret[i] = true; solve(j, j); return; } int k = best[i][j]; if (query(i, i + k)) { solve(i, i + k); } else { solve(i + k, max(j, i + k)); } } vb find_positive() { memo.clear(); ret = vb(n, false); if (P != 0) solve(0, 0); return ret; } int main() { int T; scanf("%d %lf %d", &n, &P, &T); calcDP(); // You may perform any extra initialization here. for (int i = 0; i < T; i++) { std::vector<bool> answer = find_positive(); assert(answer.size() == (size_t)n); std::string answer_str(n, ' '); for (int j = 0; j < n; j++) answer_str[j] = answer[j] ? '1' : '0'; printf("A %s\n", answer_str.c_str()); fflush(stdout); char verdict; scanf(" %c", &verdict); if (verdict == 'W') exit(0); } return 0; }

Compilation message (stderr)

Main.cpp: In function 'bool test_students(vb)':
Main.cpp:48:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   48 |     scanf(" %c", &answer);
      |     ~~~~~^~~~~~~~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:117:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  117 |     scanf("%d %lf %d", &n, &P, &T);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:135:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  135 |         scanf(" %c", &verdict);
      |         ~~~~~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...