Cod sursa(job #1613532)

Utilizator raluca1234Tudor Raluca raluca1234 Data 25 februarie 2016 14:15:11
Problema Gropi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <cstdio>
#include <algorithm>
#define MAXN 100000
using namespace std;

struct groapa{
    int x, y;
}g[MAXN+5];
struct interval{
    int st, dr, lin;
}v[100000];
int n;

bool cmp(groapa a, groapa b){
    return a.y<b.y;
}

int caut(int st, int dr, int val){
    int m;
    if (st>dr)
        return -1;
    else{
        m=(st+dr)/2;
        if (val>=v[m].st && val<=v[m].dr)
            return m;
        if (val<=v[m].st)
            return caut(st, m-1, val);
        else return caut(m+1, dr, val);
    }
}

inline int gropiintre(int y1, int y2){
    int st, dr, mij;
    st=1; dr=n;
    while (st<=dr){
        mij=(st+dr)/2;
        if (g[mij].y < y1) st=mij+1;
        else if (g[mij].y > y2) dr=mij-1;
        else return 1;
    }
    return 0;
}

int main(){
    int c, i, stanga, nrint, m, q, x1, y1, x2, y2, ans, z1, z2, gpoz;
    freopen("gropi.in", "r", stdin);
    freopen("gropi.out", "w", stdout);
    scanf("%d%d", &c, &n);
    for (i=1; i<=n; i++)
        scanf("%d%d", &g[i].x, &g[i].y);
    sort(g+1, g+n+1, cmp);
    stanga=1;
    nrint=0;
    g[n+1].x=(g[n].x+1)%3;
    g[n+1].y=c+1;

    for (i=2; i<=n+1; i++){
        if (g[i].x!=g[i-1].x){
            nrint++;
            v[nrint].st=stanga;
            v[nrint].dr=g[i].y-1;
            stanga=g[i].y;
            v[nrint].lin=g[i-1].x;
        }
    }
    scanf("%d", &m);
    for (q=1; q<=m; q++){
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        if (y1>y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        ans=y2-y1+1;

        z1=caut(1, nrint, y1);
        z2=caut(1, nrint, y2);

        if (z1==z2){ //in aceeasi zona
            if (x1!=x2) //pe linii diferite
                ans++;
            else //pe aceeasi linie
                if (x1!=v[z1].lin) //pe linia fara gropi
                    ans+=0;
                else //pe linia cu gropi
                {
                    //Verific daca am gropi intre poz de inceput si cea de sf
                    if (gropiintre(y1,y2)==1)
                        ans+=2;
                    else ans+=0;
                }
        }
        else { //in zone diferite
            ans+=z2-z1-1;
            if (x1==v[z1].lin){
                if (gropiintre(y1, v[z1].dr)==1)
                    ans+=2;
                else
                    ans+=0;
            }
            else ans+=1;

            if (x2==v[z2].lin){
                if (gropiintre(v[z2].st, y2)==1)
                    ans+=1;
                else ans+=0;
            }
            else ans+=0;
        }
        printf("%d\n", ans);
    }

    return 0;
}