programming challenges 2012 from dusk till dawn - andstudy/forge GitHub Wiki

μ΅œμ„±κΈ°

μ†ŒμŠ€μ½”λ“œ

#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <fstream>

using namespace std;

struct Route;

struct Terminal
{
    Terminal() : timeArrive( 10000 ), count( 10000 ) {}

    int				count;			// ν•΄λ‹Ή μ—­ λ„μ°©κΉŒμ§€ ν•„μš”ν•œ 리터 수.
    int				timeArrive;		// ν•΄λ‹Ή 역에 λ„μ°©ν•œ μ‹œκ°.
    string			strName;		// μ—­ 이름
    vector<Route*>	routes;			// μ—­μ—μ„œ μΆœλ°œν•˜λŠ” λ…Έμ„  데이터.
};

struct Route
{
    Route() : pStart( NULL ), pEnd( NULL ), timeStart( 0 ), timeDuration( 0 ) {}

    Terminal*	pStart;			// μΆœλ°œμ—­
    Terminal*	pEnd;			// 도착역
    int			timeStart;		// μΆœλ°œμ‹œκ°
    int			timeDuration;	// μ†Œμš”μ‹œκ°„

    int GetArriveTime() const { return timeStart + timeDuration; }
};

class Graph
{
public:
    Graph( istream& stm ) : m_stmIn( stm ) {}
    void Solve();

protected:
    void Init();

    Terminal* RegistTerminal( const string& strTerminal );
    Terminal* GetTerminal( const string& strTerminal );

    // search
    void Bfs( Terminal* pStart, Terminal* pEnd );

    //------------------------------------------------------------------------

    map<string,Terminal>	m_terminals;		// μ •λ₯˜μž₯ 리슀트
    vector<Route*>          m_routes;			// λ…Έμ„  리슀트
    istream&                m_stmIn;			// νŒŒμΌμž…λ ₯ or STDIN μž…λ ₯.
};

void Graph::Init()
{
    for( size_t i = 0; i < m_routes.size(); i++ )
    {
        delete m_routes[i];
        m_routes[i] = NULL;
    }

    m_terminals.clear();
    m_routes.resize(0);
}

Terminal* Graph::RegistTerminal( const string& strTerminal )
{
    map<string,Terminal>::iterator mit;
    mit = m_terminals.find( strTerminal );
    if( mit != m_terminals.end() )
        return &mit->second;

    // insertion.
    m_terminals[strTerminal].strName = strTerminal;

    return &m_terminals[strTerminal];
}

void Graph::Bfs( Terminal* pStart, Terminal* pEnd )
{
    queue<Terminal*> queue;

    queue.push( pStart );
    pStart->count = 0;
    pStart->timeArrive = 0;

    while( !queue.empty() )
    {
        Terminal* pTerminal = queue.front();
        queue.pop();

        // λͺ©μ μ§€μ— ν•œ 번 λ„λ‹¬ν–ˆλ”λΌλ„ λ‹€μŒμœΌλ‘œ μ§„ν–‰. 더 짧은 경둜λ₯Ό 찾을 수 μžˆλ‹€.
        if( pTerminal == pEnd )
        {
            continue;
        }

        const vector<Route*>& edges = pTerminal->routes;
        vector<Route*>::const_iterator vit;
        for( vit = edges.begin(); vit != edges.end(); vit++ )
        {
            const Route& route = *(*vit);

            // 당일에 μž μ„ μžμ§€ μ•Šκ³  λ‹€μ‹œ μ—¬ν–‰ν•  수 μžˆλŠ” 쑰건
            // 1. μΆœλ°œμ—­μ— λ„μ°©ν•œ μ‹œκ°„λ³΄λ‹€ 더 뒀에 μΆœλ°œν•˜λŠ” 열차일 것.
            // 2-1. 도착역에 이미 더 λΉ λ₯Έ 경둜둜 λ°©λ¬Έν•œ 적이 μ—†κ±°λ‚˜
            // 2-2. λ™μΌν•œ μ†Œμš”κΈ°κ°„μ΄λΌλ„ λ„μ°©μ‹œκ°„μ„ 단좕할 수 μžˆλŠ” 경우.
            if( pTerminal->timeArrive <= route.timeStart &&
                ( route.pEnd->count > pTerminal->count ||
                  ( route.pEnd->count == pTerminal->count && 
                    route.pEnd->timeArrive > route.GetArriveTime() ) ) )
            {
                queue.push( route.pEnd );
                route.pEnd->count = pTerminal->count;
                route.pEnd->timeArrive = route.GetArriveTime();
            }

            // ν•œμˆ¨ 자고 λ‹€μŒλ‚  μ—¬ν–‰ν•˜λŠ” 경둜의 탐색 쑰건
            // 1-1. 도착역에 ν˜„μž¬ μ†Œμš”μΌμž+1 만큼 짧은 방문기둝이 μ—†κ±°λ‚˜
            // 1-2. ν˜„μž¬ μ†Œμš”μΌμž+1의 기둝이 μžˆλ”λΌλ„ λ„μ°©μ‹œκ°„ 단좕이 κ°€λŠ₯ν•œ 경우.
            else if( route.pEnd->count > pTerminal->count + 1 ||
                ( route.pEnd->count == pTerminal->count + 1 && 
                  route.pEnd->timeArrive > route.GetArriveTime() ) )
            {
                queue.push( route.pEnd );
                route.pEnd->count = pTerminal->count + 1;
                route.pEnd->timeArrive = route.GetArriveTime();
            }
        }
    }

}

Terminal* Graph::GetTerminal( const string& strTerminal )
{
    map<string,Terminal>::iterator mit = m_terminals.find( strTerminal );

    if( mit == m_terminals.end() )
        return NULL;

    return &mit->second;
}

void Graph::Solve()
{
    int caseCount = 0;
    m_stmIn >> caseCount;
    m_stmIn.get();

    for( int i = 0; i < caseCount; i++ )	// ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 개수만큼 루프.
    {
        Init();

        int edgeCount = 0;
        string inputLine;
        m_stmIn >> edgeCount;
        m_stmIn.get();
        for( int j = 0; j < edgeCount; j++ ) // μ—΄μ°¨λ…Έμ„  개수만큼 루프.
        {
            string strStart, strEnd;
            int timeStart, timeDuration;
            m_stmIn >> strStart >> strEnd >> timeStart >> timeDuration;
            m_stmIn.get();

            timeStart %= 24;

            int timeArrive = timeStart + timeDuration;
            if( (6 <= timeStart && timeStart < 18) ||	// μΆœλ°œμ‹œκ°μ΄ 6:00 ~ 18:00 사이
                (timeStart < 6 && timeArrive > 6) ||	// μƒˆλ²½ 좜발인데 λ„μ°©μ‹œκ°„ 06:00 초과
                (timeStart >= 18 && timeArrive > 30) )	// 저녁 좜발인데 λ„μ°©μ‹œκ°„ λ‹€μŒλ‚  06:00 초과
            {
                continue;
            }

            Route* pRoute = new Route;
            pRoute->pStart = RegistTerminal( strStart );
            pRoute->pEnd = RegistTerminal( strEnd );
            pRoute->timeStart = (timeStart + 12) % 24;
            pRoute->timeDuration = timeDuration;
            pRoute->pStart->routes.push_back( pRoute );

            m_routes.push_back( pRoute );
        }

        string strStart, strEnd;
        m_stmIn >> strStart >> strEnd;
        m_stmIn.get();

        Terminal* pStart = GetTerminal( strStart );
        Terminal* pEnd = GetTerminal( strEnd );

        cout << "Test Case " << i + 1 << "." << endl;
        if( pStart && pEnd )
        {
            Bfs( pStart, pEnd );
        }

        if( pEnd && pEnd->timeArrive < 30 )
            cout << "Vladimir needs " << pEnd->count << " litre(s) of blood." << endl;
        else
            cout << "There is no route Vladimir can take." << endl;
    }
}

int main( int argc, char* argv[] )
{
    if( argc > 1 ) // λͺ…λ Ήν–‰ 인자λ₯Ό λ°›λŠ”λ‹€λ©΄ ν•΄λ‹Ή μ΄λ¦„μ˜ νŒŒμΌμ„ μΈν’‹μœΌλ‘œ μ‚ΌλŠ”λ‹€.
    {
        ifstream fstm( argv[1] );
        Graph g( fstm );
        g.Solve();
    }
    else // κ·Έλƒ₯ μ‹€ν–‰ν•˜λ©΄ ν‘œμ€€μž…λ ₯으둜 인풋을 λ°›μŒ.
    {
        Graph g( cin );
        g.Solve();
    }

    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️