Cod sursa(job #2957383)

Utilizator Xutzu358Ignat Alex Xutzu358 Data 22 decembrie 2022 15:13:44
Problema Cautare binara Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.29 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("cautbin.in");
ofstream g("cautbin.out");

/**
Se da un sir de numere ordonat crescator cu N elemente,
si se cere sa se raspunda la M intrebari de tipul:

0 x - cea mai mare pozitie pe care se afla un element
cu valoarea x sau -1 daca aceasta valoare nu se gaseste in sir

1 x - cea mai mare pozitie pe care se afla un element
cu valoarea mai mica sau egala cu x in sir.
Se garanteaza ca cel mai mic numar al sirului este mai mic sau egal decat x

2 x - cea mai mica pozitie pe care se afla un element
cu valoarea mai mare sau egala cu x in sir.
Se garanteaza ca cel mai mare numar din sir este mai mare sau egal decat x
**/

int n,m;
int v[100005];
int op,x;



int caut_max_poz_x() {
    int st=1, dr=n;
    /// daca nu se garanteaza chestiile de la 2 si 3 (faptu ca sigur exista un nr de genu)

    /// var 1
    /// atunci ar trb ca st = 0, dr = n+1, iar:
    /// v[0] = -inf, v[n+1] = +inf

    /// var 2
    /// la final, cand st==dr, verificam daca v[st] (sau v[dr]) verifica conditia ceruta pt ce am cautat

    while (st!=dr) {
        /// de obicei, avem asa:
        /**
        mij = (st+dr)/2  (sau mij = (st+dr+1)/2, asta conteaza mai mult in momentul in care ajungem cu st == dr-1)
        if (...) (st = mij / st = mij+1  / dr = mij / dr = mij-1)
        else (...) (dr = mij-1 / dr = mij / st = mij+1 / st = mij)
        **/

        ///var 1
        int mij = (st+dr+1)/2; /// se modifica cu +1 (sau nu) depinzand de cazul final (dr-st == 1), a.i. sa nu intram in ciclu infinit
        if (v[mij]>x) {
            dr = mij-1;
        }
        else st = mij; /// if (v[mij]<=x)
        /// obtinem cea mai mare pozitie pe care se afla el x (daca se afla)

        ///var 2
        /**
        int mij = (st+dr+1)/2;
        if (v[mij]<=x) {
            st = mij; /// daca e egal cu x => nu ne intereseaza ce e in stanga din moment ce avem nevoie de cea mai mare
            /// pozitie, dar avem nevoie de el din mijloc
        }
        else dr = mij-1;
        **/

    }
    if (v[st]==x) return st;
    return -1;
}

int caut_min_poz_x() {
    int st=1, dr = n;
    while (st!=dr) {
        /// sa presupunem ca ni se cere cea mai mica pozitie
        int mij = (st+dr)/2;
        if (v[mij]>=x) dr = mij;
        else st = mij+1;
    }

    if (v[st]==x) return st;
    return -1;
}

int caut_mai_mic_egal_x() {
    ///cea mai mare pozitie
    int st = 1, dr = n;
    while (st!=dr) {
        int mij = (st+dr+1)/2;
        if (v[mij]<=x) {
            st = mij;
        }
        else dr = mij-1;
    }
    return st;
}

int caut_mai_mare_egal_x() {
    /// cea mai mica pozitie
    int st = 1, dr = n;
    while (st!=dr) {
        int mij = (st+dr)/2;
        if (v[mij]>=x) dr = mij;
        else st = mij+1;
    }
    return st;
}

int main()
{
    f >> n;
    for (int i=1;i<=n;i++) {
        f >> v[i];
    }
    f >> m;
    for (int i=1;i<=m;i++) {
        f >> op >> x;
        if (op==0) {
            g << caut_max_poz_x(); /// << " " << caut_min_poz_x();
        }
        else if (op==1) {
            g << caut_mai_mic_egal_x();
        }
        else {
            g << caut_mai_mare_egal_x();
        }
        g << '\n';
    }
    return 0;
}