Cod sursa(job #1615993)

Utilizator Dddarius95Darius-Florentin Neatu Dddarius95 Data 27 februarie 2016 00:25:46
Problema Cautare binara Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.53 kb
/*  Cautare binara - O(logn)
    Cum cautam un element intr-un vector sortat crescator/descrescator?
    1. Cea mai mica pozitie unde am un element mai mare sau egal cu x.
        Exemplu: 0 1 2 3 4 5 6 7
                -1 2 3 4 7 7 7 9
                    Daca x = 4 => poz = 3
                    Daca x = 6 => poz = 4
        Solutie:
        int poz = upper_bound(v.begin(), v.end(), valoare) - v.begin();
            -returneaza un iterator catre primul element mai mare
        decat valoare (adica cauta v[i] > valoare, i minim). Eu nu vreau > ci >=, asa ca nu il caut pe
        x, ci pe x - 1 (adic v[i] > x -1, care cuprinde v[i] >= x).
            - am zis ca am deja un iterator catre elementul gasit (e ca si cum as avea un j). Ca sa obtin
        pozitia scad interatorul catre primul element ( e ca si cum as face poz = j - i).

    2. Cea mai mare pozitie pe care se afla un element cu valoarea mai mica sau egala cu x in sir.
        Exemplu: 0 1 2 3 4 5 6 7
                -1 2 3 4 7 7 7 9
            Daca x = 4 => poz = 3
            Daca x = 6 => poz = 3
        Solutie:
        lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1;
        Analog 1) doar ca aici parametrul este x+1 si din pozitie scad 1. Lower cauta v[i] > x, i maxim, de aia pun x+1 si scad 1.

    Daca vreau sa gasesc pe x (pozitia pe care se afla x; daca x apare de mai multe ori, nu ma intereseaza pe care il gasesc)
    atunci pot folosi oricare din cele 2 metode + verificare ca v[poz] == x

*/

#include <fstream>
#include <algorithm> // pentru f
#include <vector>
#define nmax 100099
using namespace std;
ifstream f("cautbin.in");
ofstream g("cautbin.out");

int n, m, poz;
vector<int> v;

//cea mai mare pozitie pe care se afla un element cu valoarea x
//sau -1 daca aceasta valoare nu se gaseste in sir
int cb(vector<int>& v, const int& x) {
  int poz = upper_bound(v.begin(), v.end(), x-1) - v.begin();
  // int poz = lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1; // merge si asta

  //  verific daca functia de cautare mi-a gasit elementul dorit
  if(poz >= 0 && poz < (int)v.size() && v[poz] == x) {
    return poz; // da, elementul exista
  }
  return -1;
}

//cea mai mare pozitie pe care se afla un element cu valoarea
//mai mica sau egala cu x in sir.
int cb_down(vector<int>& v, const int& x){
  int poz = lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1;

  //  verific daca functia de cautare mi-a gasit elementul dorit
  if(poz >= 0 && poz < v.size() && v[poz] <= x) {
    return poz; // da, elementul exista
  }
  return -1;
}

//cea mai mica pozitie pe care se afla un element cu valoarea
//mai mare sau egala cu x in sir.
int cb_up(vector<int>& v, const int& x) {
  int poz = upper_bound(v.begin(), v.end(), x-1) - v.begin();

  //  verific daca functia de cautare mi-a gasit elementul dorit
  if(poz >= 0 && poz < v.size() && v[poz] >= x) {
    return poz; // da, elementul exista
  }
  return -1;
}

int main() {
  f >> n;
  for(int i = 1; i <= n; ++i) {
    int x;
    f >> x;
    v.push_back(x);
  }
  f >> m;

  for(int i = 1; i <= m; ++i) {
      int tip, x;
      f >> tip >> x;

      if(!tip) {
        poz = cb(v, x);
        if (poz != -1) g << poz+1 << '\n';
                else   g << -1 << '\n';
      }

      if(tip == 1) {
        poz = cb_down(v, x);
        if (poz != -1) g << poz+1 << '\n';
                else   g << -1 << '\n';
      }

      if(tip == 2) {
        poz = cb_up(v, x);
        if (poz != -1) g << poz+1 << '\n';
                else   g << -1 << '\n';
      }
  }
  f.close();g.close();
  return 0;
}