Skip to content

14221: 【原4221】战士

题目

题目描述

author: Shuhao Li 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4221

Description

在X轴上有N个战士沿直线移动,每个战士有不同的初始位置,有的向左移动,有的向右移动,他们移动的速度是一样的。每一位战士都有一个武力值,当两战士相遇,武力值大的会瞬间将武力值小的干掉然后继续移动(干掉的过程不计时间)。

输入从左到右给出每位战士的武力值大小和移动的方向(0表示向左,1表示向右)。当经过足够长的时间之后,还剩下多少位战士?

Input Format

第一行一个整数N,表示战士的总数。

接下来总共N行,每行描述战士的武力值大小和移动方向。

第2到N+1行,每行两个整数a[i], b[i]。a[i]表示战士的武力值大小,b[i]表示移动方向,0表示向左,1表示向右。

Output Format

输出一个整数,表示经过足够长的时间以后,还剩下的战士的数目。

Sample Input

5
4 0
3 1
2 0
1 0
5 0

Sample Output

2

Limits

对于50%的数据,N <= 10000。

对于100%的数据,N <= 500000,0 <= a[i] < 10^8, b[i] = 0或1。

BugenZhao's solution

//
// Created by BugenZhao on 2019/4/10.
//

//
// Created by BugenZhao on 2019/4/5.
//

#ifndef SBL_BSTACK_H
#define SBL_BSTACK_H


template<typename Item>
class BStack {
    class Node {
    public:
        Item item;
        Node *next;

        explicit Node(const Item &item, Node *next = nullptr) : item(item), next(next) {}

        explicit Node(Node *next = nullptr) : next(next) {}

        virtual ~Node() = default;
    };

    int N;
    Node *top;

public:
    BStack() {
        top = nullptr;
        N = 0;
    }

    void push(const Item &item) {
        top = new Node{item, top};
        ++N;
    }

    Item peek() {
        return top->item;
    }

    Item pop() {
        Node *tmp = top;
        Item ret = top->item;
        top = top->next;
        delete tmp;
        --N;
        return ret;
    }

    int size() {
        return N;
    }

    void clear() {
        Node *tmp;
        while (top) {
            tmp = top;
            top = top->next;
            delete tmp;
        }
        top = nullptr;
        N = 0;
    }

    bool isEmpty() {
        return top == nullptr;
    }

    virtual ~BStack() {
        Node *tmp;
        while (top) {
            tmp = top;
            top = top->next;
            delete tmp;
        }
    }

private:
    class Iterator {
        Node *it;
        Node *top;
    public:

        Iterator(Node *top) : it(top), top(top) {}

        bool hasNext() const {
            return it != nullptr;
        }

        Item &next() {
            Node *p = it;
            it = it->next;
            return p->item;
        }

        const Item &next() const {
            Node *p = it;
            it = it->next;
            return p->item;
        }
    };

public:
    Iterator iterator() const {
        return Iterator(top);
    }
};


#endif //SBL_BSTACK_H


class S {
public:
    int power;
    bool dir;
};


#include <iostream>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int N;
    cin >> N;

    BStack<S> stack;

    int power;
    bool dir;
    for (int i = 0; i < N; ++i) {
        cin >> power >> dir;

        while (!stack.isEmpty()) {
            if (stack.peek().dir == 0 || stack.peek().dir == dir) {
                stack.push(S{power, dir});
                break;
            } else {
                if (stack.peek().power >= power) {
                    break;
                } else {
                    stack.pop();
                }

            }
        }
        if (stack.isEmpty()) {
            stack.push(S{power, dir});
        }
    }
    cout << stack.size() << endl;
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "stack"
#include "cstdio"
using namespace std;

stack<int> stack_data;

int main() {
    int n;
    scanf("%d", &n);


    int ans = 0;
    for (int i = 0; i < n; ++i) {
        int val, direction;
        scanf("%d %d", &val, &direction);
        if (direction) {
            stack_data.push(val);
        }
        else {
            while (!stack_data.empty()) {
                if (val >= stack_data.top())
                    stack_data.pop();
                else {
                    --ans;
                    break;
                }
            }
            ++ans;
        }
    }
    printf("%d", (int)stack_data.size() + ans);

    return 0;
}

skyzh's solution

#include <iostream>
#include <cstdio>
using namespace std;

int val[500003] = { 0 };
int dir[500003] = { 0 };

template <typename T>
class Stack {
public:
    T *data;
    int top_ptr;
    Stack(int cap) : data(new T[cap]), top_ptr(0) {}
    ~Stack() { delete[] data; }
    void push(const T& d) { data[top_ptr++] = d; }
    T pop() { return data[--top_ptr]; }
    T top() { return data[top_ptr - 1]; }
    bool empty() { return top_ptr == 0; }
};

int main() {
    int n;
    scanf("%d", &n);
    int l_ans = 0;
    for (int i = 0; i < n; i++) scanf("%d%d", &val[i], &dir[i]);
    Stack <int> x(500003);
    for (int i = n - 1; i >= 0; i--) {
        if (dir[i] == 0) {
            x.push(val[i]);
        } else {
            while (!x.empty() && val[i] > x.top()) {
                x.pop();
            }
            if (x.empty()) ++l_ans;
        }
    }
    printf("%d\n", l_ans + x.top_ptr);
    return 0;
}