Cod sursa(job #1357372)

Utilizator vlad.maneaVlad Manea vlad.manea Data 23 februarie 2015 21:42:24
Problema Heapuri Scor 40
Compilator java Status done
Runda Arhiva educationala Marime 4.79 kb
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

class MinHeap<T extends Comparable<T>> {
	private List<T> values = new ArrayList<T>();
	private Map<T, Integer> positions;

	public MinHeap(Map<T, Integer> positions) {
		this.positions = positions;
	}

	public void deleteValueFromPosition(int position) {
		if (position < 0 || position >= values.size()) {
			return;
		}

		swap(position, values.size() - 1);
		positions.remove(values.get(values.size() - 1));
		values.remove(values.size() - 1);
		position = Math.min(position, values.size() - 1);

		int fatherPosition = fatherPosition(position);

		if (fatherPosition >= 0
				&& values.get(position).compareTo(values.get(fatherPosition)) < 0) {
			percolate(position);
		} else {
			sift(position);
		}
	}

	public void insertValue(T value) {
		values.add(value);
		positions.put(value, values.size() - 1);
		percolate(values.size() - 1);
	}

	public T getMinValue() {
		if (values.size() <= 0) {
			return null;
		}

		return values.get(0);
	}

	private void sift(int position) {
		// Going downwards

		T currentValue = values.get(position);
		int childPosition = getPositionOfMinimumChild(position);

		if (childPosition < 0) {
			return;
		}

		T minChildValue = values.get(childPosition);

		if (minChildValue.compareTo(currentValue) >= 0) {
			return;
		}

		swap(position, childPosition);
		sift(childPosition);
	}

	private void swap(int position1, int position2) {
		T value1 = values.get(position1);
		T value2 = values.get(position2);

		positions.put(value1, position2);
		positions.put(value2, position1);

		values.set(position1, value2);
		values.set(position2, value1);
	}

	private int getPositionOfMinimumChild(int position) {
		int leftPosition = leftChildPosition(position);
		int rightPosition = rightChildPosition(position);

		if (leftPosition >= 0 && rightPosition >= 0) {
			if (values.get(leftPosition).compareTo(values.get(rightPosition)) < 0) {
				return leftPosition;
			} else {
				return rightPosition;
			}
		}

		if (leftPosition < 0 && rightPosition < 0) {
			return -1;
		}

		return leftPosition >= 0 ? leftPosition : rightPosition;
	}

	private void percolate(int position) {
		// Going upwards

		T value = values.get(position);
		int fatherPosition = fatherPosition(position);

		if (fatherPosition < 0) {
			return;
		}

		if (value.compareTo(values.get(fatherPosition)) >= 0) {
			return;
		}

		swap(position, fatherPosition);
		percolate(fatherPosition);
	}

	private int fatherPosition(int position) {
		if (position <= 0) {
			return -1;
		}

		return (position - 1) / 2;
	}

	private int leftChildPosition(int position) {
		int leftChildPosition = position * 2 + 1;

		if (leftChildPosition >= values.size()) {
			return -1;
		}

		return leftChildPosition;
	}

	private int rightChildPosition(int position) {
		int rightChildPosition = (position + 1) * 2;

		if (rightChildPosition >= values.size()) {
			return -1;
		}

		return rightChildPosition;
	}
}

class HeapNode implements Comparable<HeapNode> {
	private Integer value;

	public HeapNode(Integer value) {
		this.value = value;
	}

	public Integer getValue() {
		return value;
	}

	@Override
	public int compareTo(HeapNode arg0) {
		return this.value.compareTo(arg0.value);
	}
}

public class Main {
	public static void main(String args[]) throws IOException {
		InputStream inputStream = new FileInputStream("heapuri.in");
		Scanner scanner = new Scanner(inputStream);

		OutputStream outputStream = new FileOutputStream("heapuri.out");
		PrintWriter writer = new PrintWriter(outputStream);

		Map<HeapNode, Integer> positions = new HashMap<HeapNode, Integer>();
		List<HeapNode> order = new ArrayList<HeapNode>();
		MinHeap<HeapNode> heap = new MinHeap<HeapNode>(positions);

		int N = scanner.nextInt();

		while (N-- > 0) {
			int type = scanner.nextInt();

			switch (type) {
			case 1:
				int value1 = scanner.nextInt();
				HeapNode heapNode = new HeapNode(value1);
				order.add(heapNode);
				heap.insertValue(heapNode);
				break;
			case 2:
				int time = scanner.nextInt() - 1;
				HeapNode heapNodeTime = order.get(time);
				int position = positions.get(heapNodeTime);
				heap.deleteValueFromPosition(position);
				break;
			case 3:
				int minValue = heap.getMinValue().getValue();
				writer.println(String.valueOf(minValue));
				break;
			}
		}

		writer.flush();

		inputStream.close();
		scanner.close();
		outputStream.close();
		writer.close();
	}
}