Submission #160310

#TimeUsernameProblemLanguageResultExecution timeMemory
160310model_codeCat (info1cup19_cat)C++17
100 / 100
781 ms15340 KiB
/* Costin Solutie de 100, O (N), nu foarte constant-friendly, dar implementata elegant */ #include<bits/stdc++.h> using namespace std; const int maxM = 200000; int M, N, init[maxM + 10], a[(maxM / 2) + 10], b[(maxM / 2) + 10], c[(maxM / 2) + 10], p[(maxM / 2) + 10]; bool ap[maxM + 10]; vector < vector < int > > cycles; vector < int > oddCycleRepresentatives; vector < pair < int, int > > moves; void makeSure (int x, int l, int r) { assert (l <= x && x <= r); } void read () { scanf ("%d", &M), N = M >> 1; makeSure (M, 1, maxM); for (int i=1; i<=M; i++) ap[i] = 0; for (int i=1; i<=M; i++) { scanf ("%d", &init[i]); makeSure (init[i], 1, M); assert (!ap[init[i]]); ap[init[i]] = 1; } assert (M % 2 == 0); } void convertToNicerForm (bool &failed) { for (int i=1; i<=N; i++) a[i] = init[i], b[i] = init[M + 1 - i]; bool needJump = 0; for (int i=1; i<=N; i++) if (a[i] + b[i] != M + 1) failed = 1; else c[i] = (a[i] > N), p[i] = min (a[i], b[i]), needJump ^= c[i]; if (needJump) failed = 1; } void findCycles () { cycles.clear (); oddCycleRepresentatives.clear (); for (int i=1; i<=N; i++) ap[i] = 0; for (int i=1; i<=N; i++) if (ap[i] == 0) { int j = p[i], overallParity = 0; ap[i] = 1, overallParity ^= c[i]; vector < int > currCycle = {i}; while (j != i) currCycle.push_back (j), overallParity ^= c[j], ap[j] = 1, j = p[j]; cycles.push_back (currCycle); if (overallParity) oddCycleRepresentatives.push_back (i); } } void performSwap (int x, int y, bool xorValue) { swap (p[x], p[y]); swap (c[x], c[y]); c[x] ^= xorValue, c[y] ^= xorValue; if (!xorValue) moves.push_back ({x, y}); else moves.push_back ({x, M + 1 - y}); } void mergeCycles () { assert (oddCycleRepresentatives.size () % 2 == 0); for (int i=1; i<oddCycleRepresentatives.size (); i+=2) performSwap (oddCycleRepresentatives[i - 1], oddCycleRepresentatives[i], 0); } void solve (int i, int j, vector < int > &cycle) { if (i == j) return ; int L = cycle.size (), k = (i + 1) % L; while (1) { performSwap (cycle[i], cycle[k], 0); if (k == j) break; if (++k == L) k = 0; } } void fixCycle (vector < int > &currCycle) { int L = currCycle.size (); vector < int > needXor; for (int i=0; i<L; i++) { ap[i] = 0; if (c[currCycle[i]]) needXor.push_back (i); } assert (needXor.size () % 2 == 0); if (needXor.empty ()) { solve (0, L - 1, currCycle); return ; } for (int currPos=1; currPos<needXor.size (); currPos+=2) { int i = needXor[currPos - 1], j = needXor[currPos]; performSwap (currCycle[i], currCycle[j], 1); for (int k=i + 1; k<=j; k++) ap[k] = 1; solve (i + 1, j, currCycle); } vector < int > leftOver; for (int k=0; k<L; k++) if (!ap[k]) leftOver.push_back (currCycle[k]); solve (0, leftOver.size () - 1, leftOver); } void print () { printf ("%d %d\n", moves.size (), moves.size ()); for (auto it : moves) printf ("%d %d\n", it.first, it.second); } void check () { for (int i=1; i<=N; i++) assert (p[i] == i), assert (c[i] == 0); for (auto it : moves) { int x = it.first, y = it.second; swap (init[x], init[y]); swap (init[M + 1 - x], init[M + 1 - y]); } for (int i=1; i<=M; i++) assert (init[i] == i); } int main () { //freopen ("input", "r", stdin); //freopen ("output", "w", stdout); int tests; scanf ("%d", &tests); while (tests --) { read (), moves.clear (); bool failed = 0; convertToNicerForm (failed); if (failed) { printf ("-1\n"); continue; } findCycles (); mergeCycles (); findCycles (); assert (oddCycleRepresentatives.empty ()); for (auto &currCycle : cycles) fixCycle (currCycle); print (); check (); } return 0; }

Compilation message (stderr)

cat.cpp: In function 'void mergeCycles()':
cat.cpp:82:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i=1; i<oddCycleRepresentatives.size (); i+=2)
                   ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cat.cpp: In function 'void fixCycle(std::vector<int>&)':
cat.cpp:116:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int currPos=1; currPos<needXor.size (); currPos+=2)
                         ~~~~~~~^~~~~~~~~~~~~~~~
cat.cpp: In function 'void print()':
cat.cpp:133:52: warning: format '%d' expects argument of type 'int', but argument 2 has type 'std::vector<std::pair<int, int> >::size_type {aka long unsigned int}' [-Wformat=]
     printf ("%d %d\n", moves.size (), moves.size ());
                        ~~~~~~~~~~~~~               ^
cat.cpp:133:52: warning: format '%d' expects argument of type 'int', but argument 3 has type 'std::vector<std::pair<int, int> >::size_type {aka long unsigned int}' [-Wformat=]
cat.cpp: In function 'void read()':
cat.cpp:23:21: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf ("%d", &M), N = M >> 1;
     ~~~~~~~~~~~~~~~~^~~~~~~~~~~~
cat.cpp:29:15: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf ("%d", &init[i]);
         ~~~~~~^~~~~~~~~~~~~~~~
cat.cpp: In function 'int main()':
cat.cpp:158:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
 scanf ("%d", &tests);
 ~~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...