Submission #66508

# Submission time Handle Problem Language Result Execution time Memory
66508 2018-08-11T08:43:00 Z Eae02 Shortcut (IOI16_shortcut) C++14
0 / 100
3 ms 488 KB
#include "shortcut.h"

#include <bits/stdc++.h>

using ll = long long;

std::vector<ll> distBefore;

ll mainLineDist(int a, int b)
{
    if (a > b)
        std::swap(a, b);
    if (a == b)
        return 0;
    return distBefore[b - 1] - ((a == 0) ? 0 : distBefore[a - 1]);
}

struct Edge
{
    int length;
    int other;
};

struct Node
{
    int mlIndex;
    std::vector<Edge> edges;
};

std::vector<Node> nodes;

ll halfLoopLen;
int expA, expB, expLen;

std::vector<int> mlNodes;

const ll BIG = INT64_MAX;

bool OnLoop(const Node& n)
{
    return n.mlIndex >= expA && n.mlIndex <= expB;
}

std::pair<int, ll> FindFurthestNode(int n, int pn, ll loopDist)
{
    std::pair<int, ll> ans(n, 0);
    
    //std::pair<int, ll> minLoop(-1, BIG);
    
    for (const Edge& edge : nodes[n].edges)
    {
        if (edge.other == pn)
            continue;
        
        if (OnLoop(nodes[n]) && OnLoop(nodes[edge.other]))
        {
            ll nextLoopDist = loopDist + edge.length;
            if (nextLoopDist > halfLoopLen)
                continue;
            
            auto pAns = FindFurthestNode(edge.other, n, nextLoopDist);
            pAns.second += edge.length;
            if (pAns.second > ans.second)
                ans = pAns;
        }
        else
        {
            auto pAns = FindFurthestNode(edge.other, n, loopDist);
            pAns.second += edge.length;
            if (pAns.second > ans.second)
                ans = pAns;
        }
    }
    
    ll expNextLoopLen = loopDist + expLen;
    if (nodes[n].mlIndex == expA && nodes[pn].mlIndex != expB && expNextLoopLen <= halfLoopLen)
    {
        auto pAns = FindFurthestNode(mlNodes[expB], n, expNextLoopLen);
        pAns.second += expLen;
        if (pAns.second > ans.second)
            ans = pAns;
    }
    if (nodes[n].mlIndex == expB && nodes[pn].mlIndex != expA && expNextLoopLen <= halfLoopLen)
    {
        auto pAns = FindFurthestNode(mlNodes[expA], n, expNextLoopLen);
        pAns.second += expLen;
        if (pAns.second > ans.second)
            ans = pAns;
    }
    
    //if (minLoop.first != -1 && minLoop.second > ans.second)
    //    ans = minLoop;
    
    return ans;
}

long long find_shortcut(int n, std::vector<int> l, std::vector<int> d, int c)
{
    distBefore.resize(n - 1);
    ll distAcc = 0;
    for (int i = 0; i < l.size(); i++)
    {
        distAcc += l[i];
        distBefore[i] = distAcc;
    }
    
    expLen = c;
    
    mlNodes.resize(n);
    
    int prevMlNodeI;
    for (int i = 0; i < n; i++)
    {
        int mlNodeI = nodes.size();
        nodes.emplace_back();
        nodes[mlNodeI].mlIndex = i;
        
        mlNodes[i] = mlNodeI;
        
        if (d[i] != 0)
        {
            int slNodeI = nodes.size();
            nodes.emplace_back();
            nodes[slNodeI].mlIndex = -1;
            
            nodes[mlNodeI].edges.push_back(Edge { d[i], slNodeI });
            nodes[slNodeI].edges.push_back(Edge { d[i], mlNodeI });
        }
        
        if (i != 0)
        {
            nodes[mlNodeI].edges.push_back(Edge { l[i - 1], prevMlNodeI });
            nodes[prevMlNodeI].edges.push_back(Edge { l[i - 1], mlNodeI });
        }
        
        prevMlNodeI = mlNodeI;
    }
    
    ll ans = INT64_MAX;
    
    for (ll a = 0; a < n; a++)
    {
        for (ll b = a + 1; b < n; b++)
        {
            halfLoopLen = (mainLineDist(a, b) + c) / 2;
            
            expA = std::min(a, b);
            expB = std::max(a, b);
            
            //std::cout << a << " - " << b << std::endl;
            
            std::pair<int, ll> n1 = FindFurthestNode(0, -1, 0);
            std::pair<int, ll> n2 = FindFurthestNode(n1.first, -1, 0);
            
            //std::cout << "\t n1: " << n1.first << ", d=" << n1.second << std::endl;
            //std::cout << "\t n2: " << n2.first << ", d=" << n2.second << std::endl;
            
            ans = std::min(ans, n2.second);
            
            /*
            ll md = 0;
            
            for (ll u = 0; u < n; u++)
            {
                for (ll v = u + 1; v < n; v++)
                {
                    ll e = d[u] + d[v];
                    ll minThis = INT64_MAX;
                    minThis = std::min(minThis, mainLineDist(u, v) + e);
                    minThis = std::min(minThis, mainLineDist(u, a) + mainLineDist(v, b) + e + c);
                    minThis = std::min(minThis, mainLineDist(u, b) + mainLineDist(v, a) + e + c);
                    md = std::max(md, minThis);
                }
            }
            
            ans = std::min(ans, md);*/
        }
    }
    
    return ans;
}

Compilation message

shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:101:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < l.size(); i++)
                     ~~^~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 344 KB n = 4, 80 is a correct answer
2 Incorrect 3 ms 488 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -