Another div2 attack was triggered overnight, and the problem was solved.

Now the final test result is not available, so it is estimated that it will be ready.

Passed the pretest of the first four questions.

Update: This time rank220, It's a pitfall!

A: give you six lengths (four limbs, Head, and trunk) to determine the species. The judgment rules are very clear, but I did not pay attention to them... Hack was thrown and Wa several times.

Idea: after sorting, find four identical lengths. If there is no alien, otherwise the remaining two are equal to the elephant, or else the bear.

Code:

#include <cstdio>#include <cstring>#include <climits>#include <algorithm>using namespace std;int main() { int a[6]; register int i, j; for(i = 0; i < 6; ++i) scanf("%d", &a[i]); sort(a, a + 6); int ins = -1; for(i = 0; i <= 2; ++i) if (a[i] == a[i + 1] && a[i + 1] == a[i + 2] && a[i + 2] == a[i + 3]) { ins = i; break; } if (ins == -1) { puts("Alien"); return 0; } int tmp1, tmp2; if (ins == 0) tmp1 = a[4], tmp2 = a[5]; if (ins == 1) tmp1 = a[0], tmp2 = a[5]; if (ins == 2) tmp1 = a[0], tmp2 = a[1]; if (tmp1 == tmp2) puts("Elephant"); else puts("Bear"); return 0;}

B: There are n jobs, each of which has a difficulty, which must be completed in the order that difficulty does not drop down. If there are at least three solutions, output three of them; otherwise, output No.

Idea: first sort and find several consecutive identical blocks. Then, the factorial product of their length is the total number of solutions. First, judge whether it cannot exceed 3.

If there are three solutions, we construct the solution in this way.

(1) directly refers to the sorted sequence of labels.

(2) Based on (1), find the first two elements of the first block with a length not 1.

(3) Based on (1), find the last two elements of the block swap with the last length not 1.

It is not hard to prove that this is correct.

Code:

#include <cstdio>#include <cstring>#include <cctype>#include <iostream>#include <algorithm>using namespace std;#define N 2010struct Node { int lab, dif; Node(int _lab = 0, int _dif = 0):lab(_lab),dif(_dif){} bool operator < (const Node &B) const { return dif < B.dif; }}S[N], S1[N], S2[N];int begin[N], end[N], size[N], tot;int main() { int n; scanf("%d", &n); register int i, j, k; int x; for(i = 1; i <= n; ++i) { scanf("%d", &x); S[i] = Node(i, x); } sort(S + 1, S + n + 1); S[n + 1].dif = -1 << 30; unsigned long long res = 1; bool find = 0; for(i = 1; i <= n;) { for(j = i; S[j].dif == S[j + 1].dif; ++j); size[++tot] = j - i + 1; begin[tot] = i; end[tot] = j; for(k = 2; k <= j - i + 1; ++k) { res *= k; if (res >= 3) find = 1; } i = j + 1; } if (!find) { printf("NO"); return 0; } puts("YES"); for(i = 1; i < n; ++i) printf("%d ", S[i].lab); printf("%d\n", S[n].lab); memcpy(S1, S, sizeof(S)); for(i = 1; i <= tot; ++i) if (size[i] >= 2) { swap(S1[begin[i]], S1[begin[i] + 1]); break; } for(i = 1; i < n; ++i) printf("%d ", S1[i].lab); printf("%d\n", S1[n].lab); memcpy(S2, S, sizeof(S)); for(i = tot; i >= 1; --i) if (size[i] >= 2) { swap(S2[end[i]], S2[end[i] - 1]); break; } for(i = 1; i < n; ++i) printf("%d ", S2[i].lab); printf("%d\n", S2[n].lab); return 0;}

C: build a building with a designated poker card and ask how many different layers can be built. View the original question for details.

Apparently if a tier has t rooms, this tier consumes 3 * T-1 cards

If the total number of rooms in the I layer is AI, the total number of cards is 3*(A1 + A2 +... + as)-S

That is to say, we first determine (n + S) % 3 = 0, then s meets the condition. But also ensure that the number of rooms increases, that is, A1> = 1, AI> ai-1 (2 <= I <= s), so A1 + A2 +... + as> = (1 + s) * s/2

We know that when (n + S)/3> = (1 + s) * s/2, we can always construct a set of AI to meet the conditions. Otherwise, it must not.

Obviously, S is within the range of SQRT (N), so it can be enumerated to 10 ^ 6.

Code:

#include <cstdio>#include <cstring>#include <climits>#include <algorithm>#include <iostream>#include <cmath>using namespace std;typedef long long LL;int main() { LL n; scanf("%I64d", &n); int res = 0; register int i, j; for(i = 1; i <= 1000000 && i <= n; ++i) { if ((n + i) % 3 == 0) { LL last = (n + i) / 3; if (last >= (LL)i * (i + 1) / 2) ++res; } } printf("%d", res); return 0;}

D: Self-fill =

Idea: Perform bare KMP string matching after the difference. Pay attention to the details.

Code:

#include <cstdio>#include <cstring>#include <cctype>#include <iostream>#include <algorithm>using namespace std;#define N 200010int a1[N], a2[N], res[N], text[N], pre[N], dp[N];bool end[N];int main() { int n, w; scanf("%d%d", &n, &w); if (w == 1) { printf("%d", n); return 0; } if (n < w) { printf("0"); return 0; } register int i, j; for(i = 1; i <= n; ++i) scanf("%d", &a1[i]); for(i = 1; i <= w; ++i) scanf("%d", &a2[i]); for(i = 1; i < w; ++i) res[i] = a2[i + 1] - a2[i]; --w; for(i = 1; i < n; ++i) text[i] = a1[i + 1] - a1[i]; --n; pre[1] = 0; j = 0; res[w + 1] = (int)1e9; for(i = 2; i <= w; ++i) { while(j && res[j + 1] != res[i]) j = pre[j]; if (res[j + 1] == res[i]) ++j; pre[i] = j; } int tot = 0; j = 0; for(i = 1; i <= n; ++i) { while(j && res[j + 1] != text[i]) j = pre[j]; if (res[j + 1] == text[i]) ++j; if (j == w) ++tot; } printf("%d\n", tot); return 0;}

Codeforces round #269 (Div. 2) Solution