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; }