11215: 【原1215】bernoulli
题目
题目描述
author: DS TA 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1215
Description
实现一棵Bernoulli树。实现下列操作:
1.insert X,将整数X加入优先队列
2.delete,将优先队列中最小值弹出
3.min,输出最小值
初始优先队列为空。
Input Format
第一行含有一个正整数M(1<=M<=20000),代表总的操作数。
以下M行,每行一个操作。
Output Format
对于min操作,输出一个最小值,回车隔开。
Sample Input1
9
insert 6
insert 6
insert 4
delete
min
delete
insert 9
insert 3
min
Sample Output1
6
3
Limit
输入数据保证合法
BugenZhao's solution
//
// Created by BugenZhao on 2019/4/14.
//
#ifndef SBL_BPRIORITYQUEUE_H
#define SBL_BPRIORITYQUEUE_H
namespace bpq {
template<typename Item>
struct greater {
bool operator()(const Item &a, const Item &b) {
return a > b;
}
};
template<typename Item>
struct less {
bool operator()(const Item &a, const Item &b) {
return a < b;
}
};
}
template<typename Item, typename Comparator = bpq::greater<Item>>
class BPriorityQueue {
Comparator comparator;
Item *pq;
int N = 0;
int maxN;
private:
bool cmp(int i, int j) {
return comparator(pq[i], pq[j]);
}
void exch(int i, int j) {
Item item = pq[i];
pq[i] = pq[j];
pq[j] = item;
}
void resize(int newMaxN) {
Item *old = pq;
pq = new Item[newMaxN + 1];
int length = newMaxN > maxN ? maxN : newMaxN;
for (int i = 0; i < length; ++i) {
pq[i] = old[i];
}
delete[] old;
}
void swim(int k) {
while (k > 1 && cmp(k, k / 2)) {
exch(k / 2, k);
k /= 2;
}
}
void sink(int k) {
int j;
while (2 * k <= N) {
j = 2 * k;
j += (j < N && cmp(j + 1, j));
if (cmp(k, j)) break;
else {
exch(k, j);
k = j;
}
}
}
public:
BPriorityQueue() {
BPriorityQueue(1);
}
BPriorityQueue(int maxN) : maxN(maxN) {
pq = new Item[maxN + 1];
}
BPriorityQueue(const Item *pq, int size) {
maxN = N = size;
this->pq = new Item[size];
for (int i = 1; i <= N; ++i) {
this->pq[i] = pq[i - 1];
}
for (int k = N / 2; k >= 1; --k) {
sink(k);
}
}
bool isEmpty() {
return N == 0;
}
int size() {
return N;
}
void insert(const Item &item) {
if (N == maxN)
resize(2 * N);
pq[++N] = item;
swim(N);
}
Item pop() {
if (N <= maxN / 4)
resize(maxN / 2);
Item item = pq[1];
exch(1, N);
--N;
sink(1);
return item;
}
const Item &peek() {
return pq[1];
}
virtual ~BPriorityQueue() {
delete[] pq;
}
};
#endif //SBL_BPRIORITYQUEUE_H
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int N;
cin >> N;
BPriorityQueue<int, bpq::less<int>> pq(N);
char cmd[10];
int tmp;
while (N--) {
cin >> cmd;
switch (cmd[0]) {
case 'i':
cin >> tmp;
pq.insert(tmp);
break;
case 'd':
pq.pop();
break;
case 'm':
cout << pq.peek() << '\n';
break;
}
}
cout << endl;
return 0;
}
ligongzzz's solution
#include "iostream"
#include "cstdio"
#include "cstring"
using namespace std;
template <class T>
class mVector {
T** vector_data = nullptr;
unsigned int size = 0;
unsigned int capacity = 0;
public:
//构造函数
mVector() = default;
mVector(unsigned int _size) :size(_size) {
capacity = _size * 2;
vector_data = new T * [capacity] {nullptr};
}
mVector(unsigned int _size, const T& val) :size(_size) {
capacity = _size * 2;
vector_data = new T * [capacity] {nullptr};
for (unsigned int i = 0; i < _size; ++i)
vector_data[i] = new T(val);
}
mVector(const mVector<T> & _vector) :size(_vector.size), capacity(_vector.capacity) {
vector_data = new T * [capacity] {nullptr};
for (int i = 0; i < size; ++i)
vector_data[i] = new T(*_vector.vector_data[i]);
}
//析构函数
~mVector() {
for (unsigned int i = 0; i < size; ++i)
delete vector_data[i];
delete[] vector_data;
}
//迭代器
class iterator {
T** pos = nullptr;
friend iterator mVector<T>::begin();
friend iterator mVector<T>::end();
friend void mVector<T>::erase(const iterator& val);
public:
iterator() = default;
iterator(const iterator& other) {
pos = other.pos;
}
iterator& operator++() {
++pos;
return *this;
}
iterator operator++(int) {
iterator temp(*this);
++pos;
return temp;
}
iterator& operator--() {
--pos;
return *this;
}
iterator operator--(int) {
iterator temp(*this);
--pos;
return temp;
}
bool operator==(const iterator& other) const {
return pos == other.pos;
}
bool operator!=(const iterator& other) const {
return pos != other.pos;
}
iterator& operator=(const iterator& other) {
pos = other.pos;
return *this;
}
T& operator*() const {
return **pos;
}
};
//反向迭代器
template <class U>
class reverse_iterator {
U val;
friend reverse_iterator<U> mVector<T>::rbegin();
friend reverse_iterator<U> mVector<T>::rend();
public:
U& base() {
return val;
}
reverse_iterator() = default;
reverse_iterator(const reverse_iterator<U>& other) {
val = other.val;
}
reverse_iterator(const U& other) {
val = other;
}
reverse_iterator<U>& operator++() {
--val;
return *this;
}
reverse_iterator<U> operator++(int) {
reverse_iterator<U> temp(*this);
--val;
return temp;
}
reverse_iterator<U>& operator--() {
++val;
return *this;
}
reverse_iterator<U> operator--(int) {
reverse_iterator<U> temp(*this);
++val;
return temp;
}
bool operator==(const reverse_iterator<U>& other) const {
return val == other.val;
}
bool operator!=(const reverse_iterator<U>& other) const {
return val != other.val;
}
reverse_iterator<U>& operator=(const reverse_iterator<U>& other) {
val = other.val;
return *this;
}
T& operator*() const {
return *val;
}
};
reverse_iterator<iterator> rbegin() {
auto temp = end();
--temp;
reverse_iterator<iterator> result;
result.val = temp;
return result;
}
reverse_iterator<iterator> rend() {
auto temp = begin();
--temp;
reverse_iterator<iterator> result;
result.val = temp;
return result;
}
//增加元素
void push_back(const T & val) {
if (size < capacity)
vector_data[size++] = new T(val);
else {
T** temp_data = new T * [(capacity + 1) * 2]{ nullptr };
for (unsigned int i = 0; i < size; ++i)
temp_data[i] = vector_data[i];
temp_data[size++] = new T(val);
capacity = (capacity + 1) * 2;
delete[] vector_data;
vector_data = temp_data;
}
}
//删除末尾
void pop_back() {
delete vector_data[--size];
vector_data[size] = nullptr;
}
//清空
void clear() {
for (unsigned int i = 0; i < size; ++i) {
delete vector_data[i];
vector_data[i] = nullptr;
}
size = 0;
}
//删除
void erase(const iterator & val) {
delete* val.pos;
for (auto p = val.pos; p != vector_data + size - 1; ++p)
* p = *(p + 1);
--size;
vector_data[size] = nullptr;
}
//重载运算符
T & operator[](const unsigned int& pos) {
return *vector_data[pos];
}
iterator begin() {
iterator temp;
temp.pos = vector_data;
return temp;
}
iterator end() {
iterator temp;
temp.pos = vector_data + size;
return temp;
}
};
template <class T>
class myPriorityQueue {
mVector<T> queueData;
unsigned int sizeOfQueue = 0;
bool(*cmp)(T a, T b) = [](T a, T b) {return a < b; };
//向下过滤
void percolateDown(unsigned int pos) {
while (pos * 2 <= sizeOfQueue) {
if (pos * 2 + 1 > sizeOfQueue) {
//交换
if (cmp(queueData[pos * 2], queueData[pos])) {
auto temp = queueData[pos * 2];
queueData[pos * 2] = queueData[pos];
queueData[pos] = temp;
}
break;
}
else {
bool minNum = cmp(queueData[pos * 2 + 1], queueData[pos * 2]);
if (cmp(queueData[pos * 2 + minNum], queueData[pos])) {
auto temp = queueData[pos * 2 + minNum];
queueData[pos * 2 + minNum] = queueData[pos];
queueData[pos] = temp;
pos = pos * 2 + minNum;
}
else break;
}
}
}
public:
//构建
myPriorityQueue() {
queueData.clear();
queueData.push_back((T)0);
sizeOfQueue = 0;
}
//compare函数返回父结点a与孩子结点b的关系正确与否
myPriorityQueue(bool(*compare)(T a, T b)) :cmp(compare) {
queueData.clear();
queueData.push_back(*new T);
sizeOfQueue = 0;
}
//根据数组建立堆
void buildHeap(T* eleData, unsigned int eleNum) {
queueData.clear();
sizeOfQueue = eleNum;
queueData.push_back(*new T);
for (unsigned int i = 1; i <= eleNum; i++)
queueData.push_back(eleData[i - 1]);
//向下过滤
for (unsigned int pos = eleNum / 2; pos > 0; pos--)
percolateDown(pos);
}
//判断是否空
bool empty() {
return sizeOfQueue == 0;
}
//返回队列大小
auto size() {
return sizeOfQueue;
}
//入队
void push(const T & input) {
sizeOfQueue++;
queueData.push_back(input);
//向上过滤
for (auto i = sizeOfQueue; i > 1; i = i / 2) {
//判断是否比父结点更小
if (cmp(queueData[i], queueData[i / 2])) {
//交换
auto temp = queueData[i];
queueData[i] = queueData[i / 2];
queueData[i / 2] = temp;
}
else break;
}
}
//队列最前
T top() {
return queueData[1];
}
//出队
T pop() {
auto temp = queueData[1];
queueData[1] = queueData[sizeOfQueue--];
queueData.pop_back();
percolateDown(1);
return temp;
}
};
int main() {
int M;
cin >> M;
myPriorityQueue<int> myQueue;
for (; M > 0; M--) {
char temp[100];
scanf("%s", temp);
if (strcmp(temp, "insert") == 0) {
int tempNum;
scanf("%d", &tempNum);
myQueue.push(tempNum);
}
else if (strcmp(temp, "delete") == 0) {
if (!myQueue.empty())
myQueue.pop();
}
else {
printf("%d\n", myQueue.top());
}
}
return 0;
}
Neight99's solution
#include <cstring>
#include <iostream>
using namespace std;
template <class Type>
class priorityQueue {
private:
int currentSize;
Type *array;
int maxSize;
void doubleSpace();
// void buildHeap();
void percolateDown(int);
public:
priorityQueue(int capacity = 20010);
// priorityQueue(const Type data[],int size);
~priorityQueue();
bool isEmpty() const;
void enQueue(const Type &x);
Type deQueue();
Type getHead() const;
};
template <class Type>
priorityQueue<Type>::priorityQueue(int capacity)
: maxSize(capacity), currentSize(0) {
array = new Type[capacity];
}
template <class Type>
priorityQueue<Type>::~priorityQueue() {
delete[] array;
}
template <class Type>
bool priorityQueue<Type>::isEmpty() const {
return currentSize == 0;
}
template <class Type>
Type priorityQueue<Type>::getHead() const {
return array[1];
}
template <class Type>
void priorityQueue<Type>::enQueue(const Type &x) {
if (currentSize == maxSize - 1) {
doubleSpace();
}
int hole = ++currentSize;
for (; hole > 1 && x < array[hole / 2]; hole /= 2) {
array[hole] = array[hole / 2];
}
array[hole] = x;
}
template <class Type>
Type priorityQueue<Type>::deQueue() {
Type minItem;
minItem = array[1];
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
template <class Type>
void priorityQueue<Type>::percolateDown(int hole) {
int child;
Type tmp = array[hole];
for (; hole * 2 <= currentSize; hole = child) {
child = hole * 2;
if (child != currentSize && array[child + 1] < array[child]) {
child++;
}
if (array[child] < tmp) {
array[hole] = array[child];
} else {
break;
}
}
array[hole] = tmp;
}
template <class Type>
void priorityQueue<Type>::doubleSpace() {
Type *tmp = array;
maxSize *= 2;
array = new Type[maxSize];
for (int i = 0; i < currentSize; i++) {
array[i] = tmp[i];
}
delete[] tmp;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
priorityQueue<long long> Bernoulli;
int m;
long long x;
char order[10];
cin >> m;
for (int i = 0; i < m; i++) {
cin >> order;
if (strcmp(order, "insert") == 0) {
cin >> x;
Bernoulli.enQueue(x);
} else if (strcmp(order, "delete") == 0) {
Bernoulli.deQueue();
} else if (strcmp(order, "min") == 0) {
if (!Bernoulli.isEmpty()) {
cout << Bernoulli.getHead() << '\n';
}
}
}
return 0;
}
skyzh's solution
#include <iostream>
#include <string>
#include <stack>
#include <cstring>
using namespace std;
template<typename T>
struct Heap {
T *data;
int cap, len;
Heap(int cap = 1024) : cap(cap + 1), len(0) {
data = new T[cap];
}
Heap(const Heap& that) : cap(that.cap), len(that.len) {
data = new T[cap];
memcpy(data, that.data, sizeof(T) * cap);
}
~Heap() { delete[] data; }
void push(const T &x) {
data[++len] = x;
swim(len);
}
T pop() {
swap(data[1], data[len--]);
sink(1);
return data[len + 1];
}
T top() {
return data[1];
}
bool less(int a, int b) {
if (a > len || b > len) return false;
return data[a] < data[b];
}
void swim(int idx) {
int _idx;
while (idx > 1 && less(idx, _idx = idx / 2)) {
swap(data[idx], data[_idx]);
idx = _idx;
}
}
void sink(int idx) {
int _idx;
while ((_idx = 2 * idx) <= len) {
if (_idx < len && less(_idx + 1, _idx)) _idx++;
if (less(idx, _idx)) break;
swap(data[idx], data[_idx]);
idx = _idx;
}
}
bool empty() {
return len == 0;
}
void debug() {
for (int i = 1; i <= len; i++) cerr << data[i] << " ";
cerr << endl;
}
};
int main() {
Heap<int> heap(65536);
int N, op1, op2;
cin >> N;
char cmd[200];
for (int i = 0; i < N; i++) {
cin >> cmd;
if (strcmp(cmd, "insert") == 0) {
cin >> op1;
heap.push(op1);
}
else if (strcmp(cmd, "delete") == 0) {
heap.pop();
}
else if (strcmp(cmd, "min") == 0) {
cout << heap.top() << endl;
}
}
return 0;
}
WashSwang's solution
#include <iostream>
#include <cstring>
using namespace std;
int n,heap[30000],len,x;
char cmd[20];
void minheapify(int x){
int smallest=x,l,r,tmp;
while (true) {
l=x<<1;
r=l+1;
if (l <= len && heap[l] < heap[x]) smallest = l;
if (r <= len && heap[r] < heap[smallest]) smallest = r;
if (smallest != x) {
tmp = heap[smallest];
heap[smallest] = heap[x];
heap[x] = tmp;
x = smallest;
}
else break;
}
}
void insert(int x){
int i=++len,tmp;
heap[len]=x;
while (i>1 && heap[i/2]>heap[i])
{
tmp=heap[i/2];
heap[i/2]=heap[i];
heap[i]=tmp;
i=i/2;
}
}
int pop(){
int ret=heap[1];
heap[1]=heap[len--];
minheapify(1);
return ret;
}
int main() {
cin>>n;
len=0;
for (int i=0;i<n;++i){
cin>>cmd;
if (strcmp(cmd,"insert")==0){
cin>>x;
insert(x);
}
if (strcmp(cmd,"delete")==0) pop();
if (strcmp(cmd,"min")==0) cout<<heap[1]<<endl;
}
return 0;
}
yyong119's solution
#include <iostream>
#include <queue>
#include <functional>
using namespace std;
int main() {
priority_queue<int, vector<int>, greater<int> > que;
int M; cin >> M;
while (M--) {
char op[20];
cin >> op;
switch (op[0]) {
case 'i':
int tmp; cin >> tmp; que.push(tmp); break;
case 'd':
que.pop(); break;
case 'm':
cout << que.top() << endl; break;
}
}
return 0;
}
Zsi-r's solution
#include <iostream>
#include <cstring>
using namespace std;
class myqueue
{
private:
struct node
{
int data;
node *next;
node(int x, node *N=NULL){
data = x; next = N;
}
node ():next(NULL){};
~node(){};
};
node *front,*rear;
node * move(int i) const;
public:
myqueue();
~myqueue() ;
void enqueue(int x);
int dequeue();
int getHead()const;
void sort(int x);
void traverse()const ;
};
myqueue::myqueue()
{
front = rear = NULL;
}
myqueue::~myqueue()
{
node *tmp;
while(front != NULL)
{
tmp = front;
front = front ->next;
delete tmp;
}
}
int myqueue::getHead() const
{
return front->data;
}
int myqueue::dequeue()
{
node *tmp=front;
int value = front->data;
front= front->next;
if(front==NULL)rear=NULL;
delete tmp;
return value;
}
void myqueue::sort(int x)
{
if (rear ==NULL)front = rear = new node (x);
else
{
node *p=front,*q=NULL,*tmp;
while(p!=NULL&&(p->data<x))//p==NULL时,若不分类讨论,p->data会报错,且p!=NULL要放在前面
{
q=p;
p=p->next;
}
if (q==NULL)//即应插在队头
{
front = tmp = new node(x,p);
}
else if (p==NULL)//即应插在队尾
{
rear=tmp=new node(x);
q->next = tmp;
}
else {//插在中间
tmp = new node(x, p);
q->next = tmp;
}
}
}
void myqueue::enqueue(int x)
{
if (rear ==NULL)front = rear = new node (x);
else
rear=rear->next=new node (x);
}
void myqueue::traverse()const
{
node *p = front;
while(p!=NULL)
{
cout << p->data<<endl;
p=p->next;
}
}
int main()
{
int M;
int NUM;
char movement[10];
myqueue intqueue;
myqueue output;
cin >> M;
for (int i=0;i<M;++i)
{
cin >> movement;
switch(movement[0]){
case 'i':
cin >> NUM;
intqueue.sort(NUM);
break;
case 'd':
intqueue.dequeue() ;
break;
case 'm':
output.enqueue(intqueue.getHead()) ;
break;
}
}
output.traverse();
return 0;
}