題目
http://acm.ecnu.edu.cn/problem/3264/
題意:水平線上有 N 只螞蟻,每隻螞蟻的位置及大小均不同。他們沿着 X 軸爬行,有的向左,有的向右,爬行的速度是一樣的,兩隻螞蟻相遇大一點的會吃掉小的。
現在從左到右給出每隻螞蟻的大小和爬行的方向(0 表示向左,1 表示向右)。問足夠長的時間之後,能剩下多少隻螞蟻?
解題思路
比較簡單的模擬題。
注意到輸入是從左到右的,且螞蟻行走和互相吞噬模擬成入棧和出棧,因此用掃描每一個螞蟻,用棧模擬這些過程。
對於每個螞蟻 i,若棧頂螞蟻向右 且 螞蟻 i 向左,判斷兩者大小:
- 如果前者大,則 i 被吞噬,繼續處理下一個螞蟻;
- 如果 i 大,則前者被吞噬(出棧),用新的棧頂和 i 比較;
- 如果棧空了或者兩者方向相同,則 i 終於可以進棧了
注意棧空時入棧的兩個特殊情況:初始爲空 和 新螞蟻吞噬棧頂後變空。
測試用例:
輸入
4
5 1
1 1
3 0
4 0
輸出:
1
AC代碼
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P; //first爲大小,second爲方向
#define RIGHT 1
#define LEFT 0
const int maxn = 1e5+5;
P ant[maxn];
stack<P> s;
int main()
{
ios::sync_with_stdio(false);
int n, sz, dir;
cin >> n;
for (int i = 0; i < n; ++i)
cin >> ant[i].first >> ant[i].second;
while(!s.empty())
s.pop();
for (int i = 0; i < n; ++i)
{
if(s.empty())
{
s.push(ant[i]);
continue;
}
P tp = s.top();
bool flag = true;
while (tp.second == RIGHT && ant[i].second == LEFT)
{
if(ant[i].first < tp.first) //無法進棧
{
flag = false;
break;
}
else if (ant[i].first > tp.first) //吃掉棧頂
{
s.pop();
if(s.empty()) //棧已空
break;
tp = s.top(); //新的棧頂繼續比較
}
}
if(flag) //確定入棧
s.push(ant[i]);
}
cout << s.size() << endl;
return 0;
}