Cod sursa(job #1605477)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 19 februarie 2016 02:26:00
Problema Cautare binara Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("cautbin.in");
ofstream fout("cautbin.out");

const int NMAX = 100000;

int n; int m;

int v[NMAX + 1];

int binarySearch(int x) {// a random index with v[index] == x

	int left = 1; int right = n;

	while(left <= right) {

		int mid = left + (right - left) / 2;

		if(v[mid] == x)
			return mid;
		else if(v[mid] < x)
			left = mid + 1;
		else //v[mid] > x
			right = mid - 1; 
	}

	return -1; //not found
}

int lowerBound(int x) {

	int left = 1; int right = n;

	//invariant: intervalul va contine tot timpul lower-boundul no no yes yes, primul yes adica


	while(left < right) {

		int mid = left + (right - left) / 2;

		if(v[mid] < x)//no, can discard 
			left = mid + 1;
		else //yes, mid is a yes, have to keep it in the sequence
			right = mid;
	}

	return right; //right == left 
}

int upperBound(int x) {

	int left = 1; int right = n;
	//trebuie sa gasesti un predicat care separa elementele in yes/no iar la granita se afla raspunsul tau
	//yes yes no no, vrem primul yes

	while(left < right) {

		int mid = left + (right - left + 1) / 2;

		if(v[mid] > x) //no, can discard
			right = mid - 1;
		else //yes, have to keep
			left = mid;   //have to test here always, in case of infinite loop, we have to put round up(+1), not down left = mid
	}

	return right; // right == left
}

int serachBiggestPos(int x) {

	int res = upperBound(x);

	return v[res] == x ? res : -1;
}


int main() {

	fin >> n;

	for(int i = 1; i <= n; ++i)
		fin >> v[i];

	fin >> m;

	while(m--) {

		int type; int x;
		fin >> type >> x;

		switch(type) {

			case 0 : fout << serachBiggestPos(x) << '\n'; break;
			case 1 : fout << upperBound(x) << '\n';  break;
			case 2 : fout << lowerBound(x) << '\n'; break;
		}	
	}

	return 0;
}