#大鱼吃小鱼
有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个数,表示最终剩下的鱼的数量。
##Input示例
5
4 0
3 1
2 0
1 0
5 0
##Output示例
2
####问题分析:
此题在分析后采用栈这种存储结构较为简单,但需要注意的是只有当栈顶鱼向右而将要进栈的鱼向左时才会发生大鱼吃小鱼的情况,其他的都只需要将将要进栈的鱼压入栈顶即可,因为不会发生大鱼吃小鱼的情况,读者可自行在纸上模拟
####AC代码:
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
typedef struct{
int fi;
int flag;
}fish; //定义鱼这种结构体
int main()
{
int n;
stack<fish> s;
while(~scanf("%d",&n)){
fish f;
for(int i = 1;i<=n;i++){
scanf("%d%d",&f.fi,&f.flag);
if(s.empty()){ //如果栈为空,直接将新的鱼压入
s.push(f);
continue;
}
fish a = s.top();
int sign = 1;
while(a.flag == 1 && f.flag == 0){//如果出现了即将进栈的鱼与栈顶鱼发生冲突(大鱼吃小鱼)
if(a.fi>f.fi){ //如果栈顶鱼比即将进栈的鱼大则吃掉它
sign = 0; //这里的标记改为1,表示该鱼已经被吃掉,不让其进栈
break;
}
s.pop(); //若即将进栈的鱼未被吃掉,说明栈顶鱼被吃掉
if(s.empty()) break; //若栈顶鱼被吃掉后,栈成空,则跳出循环,循环的目的是要考虑即将进栈的 鱼可能与栈顶之前的鱼也会发生冲突
a = s.top(); //执行到此,说明之前的栈顶鱼被吃掉了,而且栈不为空,所以将新的栈顶鱼赋值给a
}
if(sign) s.push(f); //在上面的for循环中,若即将进栈的鱼被吃掉了,则sign变成了0,若sign还为1说明它未与剩下的鱼发生冲突,或者,它把与它发生冲突的鱼都吃掉了
}
printf("%d\n",s.size()); //打印还剩多少鱼
}
return 0;
}