51Nod - 1289 大鱼吃小鱼
有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右。游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右)。问足够长的时间之后,能剩下多少条鱼?
有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右。游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右)。问足够长的时间之后,能剩下多少条鱼?
Input 第1行:1个数N,表示鱼的数量(1 <= N <= 100000)。
第2 - N + 1行:每行两个数A i, B i,中间用空格分隔,分别表示鱼的大小及游动的方向(1 <= A i <= 10^9,B i = 0 或 1,0表示向左,1表示向右)。
Output 输出1个数,表示最终剩下的鱼的数量。 Sample Input
5 4 0 3 1 2 0 1 0 5 0Sample Output
2
分析:
自己做的时候用vector啦,还把向左向右的先分开,再一个一个遍历啦,他别麻烦,还超时。
这一题用 栈 特别方便,特别简单!
栈 后进先出,
可以把向右的鱼存进栈里,先被吃掉的 或者说最先于 下一个 向左的鱼 进行判断的,就是后存入栈的鱼,就是栈顶。。
这样可以一边输入,一边操作,
如果 向左 的鱼特别大,!!! 那就一直 q.pop() 咯~~~直到 q 为空。 此时就 cnt ++ (cnt用来记录能一直向左游的鱼)
如果向左的鱼 遇到了 比较大的 q.top() ,那就么办法了,继续下一组输入!!!
最后 q.size () + cnt 就是最终剩下的 鱼
特别注意!!:
while( !q.empty() && a > q.top()) 这句判断向左的鱼和栈顶的鱼大小的语句。不能写成 while(a > q.top()&& !q.empty())
因为 q.top () 为空的时候执行是会出错的!!!而如果想判断 !q.empty () ,因为短路原则,就不会执行后面的判断。
#include <stack>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
int cnt = 0;
stack<int> q;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
if(b) // b == 1 表示这条鱼向右游
{
q.push(a);
}
else //如果这条鱼向左游
{
while(!q.empty() && a > q.top()) // 如果这条向左的鱼前方有向右的鱼,并且比它大,如果向左的小,被吃,就下一组输入了
q.pop(); // 前方向右的鱼被吃。
if(q.empty()) // 如果q 已经空了,说明向左的被向右的吃完了,
cnt ++; // cnt 记录最终能一直向左游的鱼
}
}
cout<<q.size() + cnt<<endl;
return 0;
}