#include <cstdlib> #include <cstdio> int times_chosen[1024 * 1024]; enum class state_t { none_found, one_found, both_found, }; bool do_single_case() { int n; scanf("%d\n", &n); int first_nonzero = -1; int last_nonzero = -1; int count_zeros = 0; for (int i = 0; i < n; i++) { scanf("%d", ×_chosen[i]); if (times_chosen[i] != 0) { last_nonzero = i; if (first_nonzero == -1) { first_nonzero = i; } } else { count_zeros++; } } if (first_nonzero == -1) { // All zeros - not really a valid test case, but whatever // printf("all zeros\n"); return false; } if (count_zeros > n - (last_nonzero + 1) + first_nonzero) { // There are some zeros within the non-zeros range - cannot proceed // printf("too many zeros (%d > %d)\n", count_zeros, n - (last_nonzero + 1) + first_nonzero); return false; } int credit = 2 * times_chosen[first_nonzero]; state_t state = state_t::none_found; // printf("Initial credit is %d\n", credit); for (int i = first_nonzero + 1; i <= last_nonzero; i++) { credit = 2 * times_chosen[i] - credit; // printf("a[%d] is %d, credit is now %d\n", i, times_chosen[i], credit); if (credit == 0) { if (state == state_t::none_found) { if (i == last_nonzero) { // printf(" at the end - returning true\n"); return true; } // The previous vertex was most likely a sink/source // printf(" transitioning to one_found, increasing credit by 1\n"); state = state_t::one_found; credit += 1; } else { // printf(" returning false 1\n"); return false; } } else if (credit == -1) { if (state == state_t::one_found) { // printf(" transitioning to both_found, increasing credit by 1\n"); state = state_t::both_found; credit += 1; } else { // printf(" returning false 3\n"); return false; } } else if (credit == -2) { if (state == state_t::none_found) { // printf(" transitioning to both_found, increasing credit by 2\n"); state = state_t::both_found; credit += 2; } else { // printf(" returning false 4\n"); return false; } } else if (credit < -2) { // printf(" returning false 5\n"); return false; } } switch (state) { case state_t::none_found: // printf(" is %d zero or two?\n", credit); return credit == 0 || credit == 2; case state_t::one_found: // ??? // printf(" is %d one?\n", credit); return credit == 1; case state_t::both_found: // printf(" is %d zero?\n", credit); return credit == 0; } } int main() { int t; scanf("%d\n", &t); while (t --> 0) { puts(do_single_case() ? "TAK" : "NIE"); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <cstdlib> #include <cstdio> int times_chosen[1024 * 1024]; enum class state_t { none_found, one_found, both_found, }; bool do_single_case() { int n; scanf("%d\n", &n); int first_nonzero = -1; int last_nonzero = -1; int count_zeros = 0; for (int i = 0; i < n; i++) { scanf("%d", ×_chosen[i]); if (times_chosen[i] != 0) { last_nonzero = i; if (first_nonzero == -1) { first_nonzero = i; } } else { count_zeros++; } } if (first_nonzero == -1) { // All zeros - not really a valid test case, but whatever // printf("all zeros\n"); return false; } if (count_zeros > n - (last_nonzero + 1) + first_nonzero) { // There are some zeros within the non-zeros range - cannot proceed // printf("too many zeros (%d > %d)\n", count_zeros, n - (last_nonzero + 1) + first_nonzero); return false; } int credit = 2 * times_chosen[first_nonzero]; state_t state = state_t::none_found; // printf("Initial credit is %d\n", credit); for (int i = first_nonzero + 1; i <= last_nonzero; i++) { credit = 2 * times_chosen[i] - credit; // printf("a[%d] is %d, credit is now %d\n", i, times_chosen[i], credit); if (credit == 0) { if (state == state_t::none_found) { if (i == last_nonzero) { // printf(" at the end - returning true\n"); return true; } // The previous vertex was most likely a sink/source // printf(" transitioning to one_found, increasing credit by 1\n"); state = state_t::one_found; credit += 1; } else { // printf(" returning false 1\n"); return false; } } else if (credit == -1) { if (state == state_t::one_found) { // printf(" transitioning to both_found, increasing credit by 1\n"); state = state_t::both_found; credit += 1; } else { // printf(" returning false 3\n"); return false; } } else if (credit == -2) { if (state == state_t::none_found) { // printf(" transitioning to both_found, increasing credit by 2\n"); state = state_t::both_found; credit += 2; } else { // printf(" returning false 4\n"); return false; } } else if (credit < -2) { // printf(" returning false 5\n"); return false; } } switch (state) { case state_t::none_found: // printf(" is %d zero or two?\n", credit); return credit == 0 || credit == 2; case state_t::one_found: // ??? // printf(" is %d one?\n", credit); return credit == 1; case state_t::both_found: // printf(" is %d zero?\n", credit); return credit == 0; } } int main() { int t; scanf("%d\n", &t); while (t --> 0) { puts(do_single_case() ? "TAK" : "NIE"); } return 0; } |