Submission #1276446

#TimeUsernameProblemLanguageResultExecution timeMemory
1276446mehrzadTriple Peaks (IOI25_triples)C++20
Compilation error
0 ms0 KiB
#include "triples.h"
#include <bits/stdc++.h>
using namespace std;

/*---------------------------------------------------------------*/
/*  return the height that would make the triple mythical,
    or -1 if impossible.
    The two known heights are h1 , h2.
    The distances are   d1 = middle-left , d3 = right-middle   (both >0)   */
static inline int needed_height(int d1, int d3, int h1, int h2)
{
    const int sum = d1 + d3;          // the largest distance
    // other two heights must be a sub‑multiset of {d1,d3,sum}
    // case 1 : they are exactly {d1,d3}  -> missing value = sum
    if ((h1 == d1 && h2 == d3) || (h1 == d3 && h2 == d1))
        return sum;
    // case 2 : they are {d3,sum}          -> missing value = d1
    if ((h1 == d3 && h2 == sum) || (h1 == sum && h2 == d3))
        return d1;
    // case 3 : they are {d1,sum}          -> missing value = d3
    if ((h1 == d1 && h2 == sum) || (h1 == sum && h2 == d1))
        return d3;
    return -1;
}

/* count all mythical triples of the current array */
static int count_all(const vector<int> &H)
{
    const int N = (int)H.size();
    int total = 0;
    for (int i = 0; i + 2 < N; ++i) {
        for (int j = i + 1; j + 1 < N; ++j) {
            const int d1 = j - i;
            for (int k = j + 1; k < N; ++k) {
                const int d3 = k - j;
                const int sum = d1 + d3;
                int a = H[i], b = H[j], c = H[k];
                // maximal height must be the sum
                int mx = a;
                if (b > mx) mx = b;
                if (c > mx) mx = c;
                if (mx != sum) continue;
                int mn = a;
                if (b < mn) mn = b;
                if (c < mn) mn = c;
                int mid = a + b + c - mx - mn;
                if ( (mn == d1 && mid == d3) || (mn == d3 && mid == d1) )
                    ++total;
            }
        }
    }
    return total;
}

/*---------------------------------------------------------------*/
std::vector<int> construct_range(int M, int K)
{
    const int N = M;                     // we use the maximal allowed size
    vector<int> H(N);
    std::mt19937 rng(123456);            // deterministic RNG

    /*--- initial array (random, deterministic) -----------------*/
    uniform_int_distribution<int> dist(1, N - 1);
    for (int i = 0; i < N; ++i) H[i] = dist(rng);

    int total = count_all(H);
    if (total >= K) return H;            // already enough

    /*--- hill climbing ------------------------------------------*/
    const int MAX_VAL = N - 1;
    vector<int> gain(MAX_VAL + 2, 0);    // reused for every position

    while (total < K) {
        bool any_change = false;

        for (int i = 0; i < N; ++i) {
            fill(gain.begin(), gain.end(), 0);
            int orig = 0;                // mythical triples that involve i at the moment

            /* i is the leftmost index */
            for (int j = i + 1; j + 1 < N; ++j) {
                const int d1 = j - i;
                for (int k = j + 1; k < N; ++k) {
                    const int d3 = k - j;
                    int need = needed_height(d1, d3, H[j], H[k]);
                    if (need == -1) continue;
                    if (H[i] == need) ++orig;
                    else ++gain[need];
                }
            }

            /* i is the middle index */
            for (int j = 0; j < i; ++j) {
                const int d1 = i - j;
                for (int k = i + 1; k < N; ++k) {
                    const int d3 = k - i;
                    int need = needed_height(d1, d3, H[j], H[k]);
                    if (need == -1) continue;
                    if (H[i] == need) ++orig;
                    else ++gain[need];
                }
            }

            /* i is the rightmost index */
            for (int j = 0; j + 1 < i; ++j) {
                for (int k = j + 1; k < i; ++k) {
                    const int d1 = k - j;
                    const int d3 = i - k;
                    int need = needed_height(d1, d3, H[j], H[k]);
                    if (need == -1) continue;
                    if (H[i] == need) ++orig;
                    else ++gain[need];
                }
            }

            int bestV = H[i];
            int bestDelta = 0;
            for (int v = 1; v <= MAX_VAL; ++v) {
                if (gain[v] == 0) continue;
                int delta = gain[v] - orig;
                if (delta > bestDelta) {
                    bestDelta = delta;
                    bestV = v;
                }
            }

            if (bestDelta > 0) {
                H[i] = bestV;
                total += bestDelta;
                any_change = true;
                if (total >= K) break;
            }
        }

        if (!any_change) break;          // local optimum reached
    }

    /* In the (extremely unlikely) case that we still have < K,
       we simply return the best we have – the statement of the
       problem allows a proportional score.  For the given limits
       the loop above always reaches K. */
    return H;
}

Compilation message (stderr)

/usr/bin/ld: /tmp/ccVRKCy6.o: in function `main':
grader.cpp:(.text.startup+0x367): undefined reference to `count_triples(std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status