难以理解为什么会超时
正确的算法可能是要更加简洁的算法?不太懂。
#include<cstdio>
#include<string.h>
#include<queue>
#include<iterator>
#include<algorithm>
#include<vector>
#include<list>
#include<stack>
using namespace std;
struct HOLE
{
long long int no;
long long int w;
long long int h;
long long int time; //when water come to this hi
};
list<HOLE>::iterator pos_mov(list<HOLE>::iterator);
//pos_pr point move function
void pos_cmb(list<HOLE>::iterator, list<HOLE>::iterator);
//combine the first sructure to the second
list<HOLE>hole;
stack<HOLE>map;
vector<HOLE>output;
int main()
{
HOLE temp;
long long int N, n;
scanf("%lld", &N);
getchar();
temp.time = 0;
long long int highest = 0;
for (n = 0; n < N; n++)
{
temp.no = n;
scanf("%lld %lld", &temp.w, &temp.h);
getchar();
hole.push_back(temp);
output.push_back(temp);
highest = (highest > temp.h) ? highest : temp.h;
}
//looking for the lowest
list<HOLE>::iterator pos1, pos2;
pos1 = hole.begin();
pos2 = hole.begin();
long long int time_sum = 0, width_sum = 0;
while (1)
{
if (pos1 == hole.end())
{
break;
}
if ((*pos1).h < (*pos2).h)
{
pos2 = pos1;
}
width_sum += (*pos1).w;
time_sum += (highest + 1 - (*pos1).h) * (*pos1).w;
pos1++;
}
//
list<HOLE>::iterator pos_pr, pos_lf, pos_rt;
long long int pos_past;
pos_pr = pos2;
pos_past = (*pos_pr).no;
pos_lf = pos_pr;
pos_rt = pos_pr; //left right present point on the same place, which means the begin
while (1)
{
if (hole.size() == 1) //when hole become one, end
{
//count
break;
}
pos_pr = pos_mov(pos_pr); //move pos_pr to correct place
pos_lf = pos_pr;
pos_rt = pos_pr;
if (pos_pr != hole.begin())
{
pos_lf--;
pos_rt++;
}
else if (pos_pr == hole.begin())
{
pos_lf = hole.end();
pos_rt++;
}
if (pos_lf != hole.end() && pos_rt != hole.end()) //pos_pr not in begin or end
{
if ((*pos_lf).h > (*pos_rt).h)
{
pos_cmb(pos_pr, pos_rt);
pos_pr = pos_rt;
}
else if ((*pos_lf).h < (*pos_rt).h)
{
pos_cmb(pos_pr, pos_lf);
pos_pr = pos_lf;
}
}
else if (pos_lf == hole.end() && pos_rt != hole.end()) //pos_pr in begin
{
pos_cmb(pos_pr, pos_rt);
pos_pr = pos_rt;
}
else if (pos_lf != hole.end() && pos_rt == hole.end()) //pos_pr in end
{
pos_cmb(pos_pr, pos_lf);
pos_pr = pos_lf;
}
}
temp.h = (hole.front()).h;
temp.w = (hole.front()).w;
temp.time = (hole.front()).w;
temp.no = (hole.front()).no;
map.push(temp);
while (1)
{
if (map.size() == 0)
{
break;
}
(output[(map.top()).no]).time = time_sum - (map.top()).time + (map.top()).w;
time_sum -= (map.top()).time;
map.pop();
}
for (n = 0; n < N; n++)
{
printf("%lld\n", (output[n]).time);
}
}
list<HOLE>::iterator pos_mov(list<HOLE>::iterator present)
{
list<HOLE>::iterator left, right, last;
int flag = 0;
left = present;
right = present;
last = present;
while (1)
{
left = present;
right = present;
if (present != hole.begin())
{
left--;
right++;
}
else if (present == hole.begin())
{
left = hole.end();
right++;
}
if (flag == 1)
{
break;
}
if (left == hole.end()) //on begin
{
if (right == hole.end())
{
flag = 1;
continue;
}
else if ((*right).h > (*present).h)
{
flag = 1;
continue;
}
else
{
last = present;
present = right;
continue;
}
}
else if (right == hole.end()) //on end
{
if ((*left).h > (*present).h)
{
flag = 1;
continue;
}
else
{
last = present;
present = left;
continue;
}
}
//on middle
else
{
if ((*left).h > (*present).h && (*right).h> (*present).h)
{
flag = 1;
continue;
}
else if ((*left).h < (*present).h && (*right).h < (*present).h)
{
if ((*left).h < (*right).h)
{
present = left;
continue;
}
else
{
present = right;
continue;
}
}
else if ((*left).h > (*present).h)
{
present = right;
}
else if ((*right).h > (*present).h)
{
present = left;
}
}
}
return present;
}
void pos_cmb(list<HOLE>::iterator Orig, list<HOLE>::iterator Desti)
{
HOLE map_temp;
map_temp.no = (*Orig).no;
map_temp.w = (*Orig).w;
map_temp.h = (*Orig).h;
map_temp.time = ((*Desti).h - (*Orig).h) * (*Orig).w;
map.push(map_temp);
(*Desti).w += (*Orig).w;
hole.erase(Orig);
}