代码改变世界

POJ 3658 Artificial Lake

2012-02-15 19:31  咆哮的马甲  阅读(247)  评论(0编辑  收藏  举报

这道题做了整整一天,一直遇到Time Limit Exceeded,估计是链表的创建以及修改指针指向比较费时。不断的修改之后才勉强达到要求。

解题思路:模拟水流由高到低的过程,单纯的模拟会超时,所以要做一些优化。

#include "stdio.h"
#include <iostream>
#define max  1000010
using namespace std;

typedef struct Level
{
    Level()
    {
        this->width = 0;
        this->height = 0;
        this->index = 0;
        this->preLevel = NULL;
        this->nextLevel = NULL;
    }

    Level(__int64 w, __int64 h, int index)
    {
        this->width = w;
        this->height = h;
        this->index = index;
        this->preLevel = NULL;
        this->nextLevel = NULL;
    }

    __int64 width;
    __int64 height;
    int index;
    Level* preLevel;
    Level* nextLevel;
} LevelNode;

__int64 time[100005];
LevelNode Nodes[100005];

int main()
{
    __int64 levelNum,nodeCount, width, height;

    __int64 total = 0;
    cin>>levelNum;
    nodeCount = levelNum;
    int index = 1;

    LevelNode* head = NULL;
    LevelNode* tail = NULL; 
    LevelNode* cur = NULL;
    while(levelNum !=0)
    {
        cin>>width>>height;
        
        Nodes[index] = LevelNode(width,height,index);
        
        if(NULL == head)
        {
            head = &Nodes[index];
            tail = &Nodes[index];
            cur = &Nodes[index];
        }
        else
        {
            tail->nextLevel = &Nodes[index];
            Nodes[index].preLevel = tail;
            tail = &Nodes[index];

            // Get the start level
            if(cur->height > Nodes[index].height)
                cur = &Nodes[index];
        }

        levelNum--;
        index++;
    }

    Nodes[0] = LevelNode(0,max,0);
    Nodes[nodeCount+1] = LevelNode(0,max,nodeCount+1);

    Nodes[0].nextLevel = head;
    head->preLevel = &Nodes[0];
    Nodes[nodeCount+1].preLevel = tail;
    tail->nextLevel = &Nodes[nodeCount+1];

    while(true)
    {
        time[cur->index] = total + cur->width;

        // left > right
        if(cur->preLevel->height >  cur->nextLevel->height)
        {
            total += cur->width * (cur->nextLevel->height - cur->height);
            cur->nextLevel->width += cur->width;
            cur->nextLevel->preLevel = cur->preLevel;
            cur->preLevel->nextLevel = cur->nextLevel;
            cur = cur->nextLevel; 

            while(cur->height > cur->nextLevel->height)
            {
                cur = cur->nextLevel;
            }
        }
        // left < right
        else if(cur->preLevel->height <  cur->nextLevel->height)
        {
             total += cur->width * (cur->preLevel->height - cur->height);
             cur->preLevel->width += cur->width;
             cur->preLevel->nextLevel = cur->nextLevel;
             cur->nextLevel->preLevel = cur->preLevel;
             cur = cur->preLevel;

             while(cur->height > cur->preLevel->height)
             {
                 cur = cur->preLevel;
             }
        }
        else
            break;
        
    }

    for(int i=0; i<nodeCount;i++)
    {
        cout<<time[i+1]<<"\n";
    }

	return 0;
}