QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#343155#7624. Mystery of PrimeLainWA 2ms4336kbC++234.1kb2024-03-01 23:46:472024-03-01 23:46:47

Judging History

你现在查看的是最新测评结果

  • [2024-03-01 23:46:47]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:4336kb
  • [2024-03-01 23:46:47]
  • 提交

answer

#include "bits/stdc++.h"
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;


// Source: bqi343+Me
// Tested On:
// Fast prime sieve in O(NloglogN)
// Also finds the number of primes <= x
template <int N = 100007>
struct Sieve {
  bitset<N> isPrime;
  vector<int> primes, cum;
  Sieve() {
    isPrime.set();
    isPrime[0] = isPrime[1] = 0;
    for (int i = 4; i < N; i += 2) isPrime[i] = 0;
    for (int i = 3; i * i < N; i += 2)
      if (isPrime[i])
        for (int j = i * i; j < N; j += 2 * i) isPrime[j] = 0;
    for (int i = 0; i < N; i++) {
      if (isPrime[i]) primes.push_back(i);
      cum.push_back(primes.size());
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  Sieve<200007> S;
  enum {
    SAME, // this is separate from 1
    ONE,
    EVEN, // this is separate from 1
    ODD, // this is separate from 1
  };

  array<int, 4> dp = {0};
  int n;
  cin >> n;
  vi a(n);
  for (auto& x :a) cin >> x;
  const int INF = 1e9;
  dp[EVEN] = 1, dp[ODD] = 1;
  if (a[0] != 1) dp[ONE] = 1;
  else dp[ONE] = 0, dp[SAME] = INF;
  rep(i, 1, n) {
    array<int, 4> ndp = {INF, INF, INF, INF};
    if (S.isPrime[a[i] + a[i-1]]) {
      // Keep things the same.
      ndp[SAME] = min(ndp[SAME], dp[SAME]);
    }
    if (S.isPrime[a[i] + 1]) {
      ndp[SAME] = min(ndp[SAME], dp[ONE]);
    }
    if (a[i] == 1) {
      // We can keep it the same if the previous number is
      // one or an undecided even number.
      ndp[ONE] = min(ndp[ONE], dp[ONE]);
      ndp[ONE] = min(ndp[ONE], dp[EVEN]);

      // We can change it to some random odd number if
      // the previous number is even.
      ndp[ODD] = min(ndp[ODD], dp[EVEN] + 1);
      if (a[i-1]%2 == 0) {
        ndp[ODD] = min(ndp[ODD], dp[SAME] + 1);
      }

      // We can change it to some random even number if
      // the previous number is odd.
      ndp[EVEN] = min(ndp[EVEN], dp[ODD] + 1);
      ndp[EVEN] = min(ndp[EVEN], dp[ONE] + 1);
      if (a[i-1] != 1 && a[i-1]%2 == 1) {
        ndp[EVEN] = min(ndp[EVEN], dp[SAME] + 1);
      }
    } else if (a[i]%2 == 1) {
      // We can keep it the same if the previous number is undecided
      // even.
      ndp[SAME] = min(ndp[SAME], dp[EVEN]);

      // We can change it to some random odd number if
      // the previous number is even.
      ndp[ODD] = min(ndp[ODD], dp[EVEN] + 1);
      if (a[i-1]%2 == 0) {
        ndp[ODD] = min(ndp[ODD], dp[SAME] + 1);
      }

      // We can change it to some random even number if
      // the previous number is odd.
      ndp[EVEN] = min(ndp[EVEN], dp[ODD] + 1);
      ndp[EVEN] = min(ndp[EVEN], dp[ONE] + 1);
      if (a[i-1] != 1 && a[i-1]%2 == 1) {
        ndp[EVEN] = min(ndp[EVEN], dp[SAME] + 1);
      }

      // We can change it to one if the previous number is one.
      ndp[ONE] = min(ndp[ONE], dp[ONE] + 1);
      if (S.isPrime[a[i-1]+1]) {
        ndp[ONE] = min(ndp[ONE], dp[SAME] + 1);
      }
    } else if (a[i]%2 == 0) {
      // We can keep it the same if the previous number is undecided
      // even.
      ndp[SAME] = min(ndp[SAME], dp[ODD]);

      // We can change it to some random odd number if
      // the previous number is even.
      ndp[ODD] = min(ndp[ODD], dp[EVEN] + 1);
      if (a[i-1]%2 == 0) {
        ndp[ODD] = min(ndp[ODD], dp[SAME] + 1);
      }

      // We can change it to some random even number if
      // the previos number is odd.
      ndp[EVEN] = min(ndp[EVEN], dp[ODD] + 1);
      ndp[EVEN] = min(ndp[EVEN], dp[ONE] + 1);
      if (a[i-1] != 1 && a[i-1]%2 == 1) {
        ndp[EVEN] = min(ndp[EVEN], dp[SAME] + 1);
      }

      // We can change it to one if the previous number is one.
      ndp[ONE] = min(ndp[ONE], dp[ONE] + 1);
      if (S.isPrime[a[i-1]+1]) {
        ndp[ONE] = min(ndp[ONE], dp[SAME] + 1);
      }
    }
    dp = std::move(ndp);
  }
  cout << *min_element(all(dp)) << '\n';
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 4336kb

input:

6
1 5 1 4 4 1

output:

2

result:

ok 1 number(s): "2"

Test #2:

score: 0
Accepted
time: 2ms
memory: 4256kb

input:

9
30 6 7 12 15 8 20 17 14

output:

4

result:

ok 1 number(s): "4"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 4264kb

input:

1568
119 519 706 1003 1317 322 25 1466 816 525 1 1122 38 1511 774 515 274 780 647 230 1602 1051 810 1 1 1232 1 1202 1583 412 1111 168 309 1181 184 1260 491 764 809 1213 804 1470 1 1087 1235 1004 673 1338 1333 1392 1036 1539 268 1 712 727 297 404 1317 36 463 1067 1133 693 931 46 1 100 1608 965 1 1406...

output:

759

result:

wrong answer 1st numbers differ - expected: '733', found: '759'