#include <cstdio> #include <algorithm> using namespace std; const int MAXN = 50004; struct RECT { int bx1, by1, bx2, by2; //begin (x1, y1) (x2, y2) int ex1, ey1, ex2, ey2; //end (x1, y1) (x2, y2) int height, maxh, end_num; }; int test, qt, height; RECT tab[MAXN], tmp[MAXN]; bool CmpBeg(const RECT &a, const RECT &b) { if(a.bx1 == b.bx1) return a.by1 <= b.by1; return a.bx1 < b.bx1; } bool CmpEnd(const RECT &a, const RECT &b) { if(a.ex1 == b.ex1) return a.ey1 <= b.ey1; return a.ex1 < b.ex1; } bool merge(int low, int high) { //scalenie dwóch zbiorów w jeden posortowany //na początek zbioru dodaje mniejszą wartość z dwóch posortowanych //już zbiorów aż do opróżnienia jednego z nich int mid=(low+high)/2; int i=low, j=mid+1; int it=low; //Wyznaczenie maxh for(int k=mid, mh=0; k>=low; k--) { if(tab[k].height > mh) mh = tab[k].height; tab[k].maxh=mh; } for(int k=high, mh=0; k>=mid+1; k--) { if(tab[k].height > mh) mh = tab[k].height; tab[k].maxh=mh; } for(; i<=mid && j<=high; it++) if(tab[j].end_num<tab[i].end_num) { if(height-(tab[j].height+tab[i].maxh) < 0) return false; tmp[it]=tab[j++]; } else tmp[it]=tab[i++]; //dopisuje "ogon" zbioru który jeszcze pozostał for(; i<=mid; it++) tmp[it]=tab[i++]; for(; j<=high; it++) tmp[it]=tab[j++]; //przepisuje tablicę for(i=low; i<=high; i++) tab[i]=tmp[i]; return true; //zwraca prawde jezeli dalo sie scalic } bool mergesort(int low, int high) { //rekurencyjne dzielenie zbioru na 2 podzbiory do uzyskania zbioru 1-elementowego //wtedy scalenie dwóch zbiorów w jeden posortowany if(low>=high) return true; int mid=(low+high)/2; return (mergesort(low, mid) && mergesort(mid+1, high) && merge(low, high)); } int main() { scanf("%d", &test); for(int t=0; t<test; t++) { scanf("%d%d", &qt, &height); for(int i=0; i<qt; i++) { scanf("%d%d%d%d", &(tab[i].bx1), &(tab[i].by1), &(tab[i].bx2), &(tab[i].by2)); if(tab[i].bx1 > tab[i].bx2) swap(tab[i].bx1, tab[i].bx2); if(tab[i].by1 > tab[i].by2) swap(tab[i].by1, tab[i].by2); tab[i].height = tab[i].by2 - tab[i].by1; } for(int i=0; i<qt; i++) { scanf("%d%d%d%d", &(tab[i].ex1), &(tab[i].ey1), &(tab[i].ex2), &(tab[i].ey2)); if(tab[i].ex1 > tab[i].ex2) swap(tab[i].ex1, tab[i].ex2); if(tab[i].ey1 > tab[i].ey2) swap(tab[i].ey1, tab[i].ey2); } sort(tab, tab+qt, CmpEnd); for(int i=0; i<qt; i++){ tab[i].end_num = i;} sort(tab, tab+qt, CmpBeg); if(mergesort(0, qt-1)) printf("TAK\n"); else printf("NIE\n"); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include <cstdio> #include <algorithm> using namespace std; const int MAXN = 50004; struct RECT { int bx1, by1, bx2, by2; //begin (x1, y1) (x2, y2) int ex1, ey1, ex2, ey2; //end (x1, y1) (x2, y2) int height, maxh, end_num; }; int test, qt, height; RECT tab[MAXN], tmp[MAXN]; bool CmpBeg(const RECT &a, const RECT &b) { if(a.bx1 == b.bx1) return a.by1 <= b.by1; return a.bx1 < b.bx1; } bool CmpEnd(const RECT &a, const RECT &b) { if(a.ex1 == b.ex1) return a.ey1 <= b.ey1; return a.ex1 < b.ex1; } bool merge(int low, int high) { //scalenie dwóch zbiorów w jeden posortowany //na początek zbioru dodaje mniejszą wartość z dwóch posortowanych //już zbiorów aż do opróżnienia jednego z nich int mid=(low+high)/2; int i=low, j=mid+1; int it=low; //Wyznaczenie maxh for(int k=mid, mh=0; k>=low; k--) { if(tab[k].height > mh) mh = tab[k].height; tab[k].maxh=mh; } for(int k=high, mh=0; k>=mid+1; k--) { if(tab[k].height > mh) mh = tab[k].height; tab[k].maxh=mh; } for(; i<=mid && j<=high; it++) if(tab[j].end_num<tab[i].end_num) { if(height-(tab[j].height+tab[i].maxh) < 0) return false; tmp[it]=tab[j++]; } else tmp[it]=tab[i++]; //dopisuje "ogon" zbioru który jeszcze pozostał for(; i<=mid; it++) tmp[it]=tab[i++]; for(; j<=high; it++) tmp[it]=tab[j++]; //przepisuje tablicę for(i=low; i<=high; i++) tab[i]=tmp[i]; return true; //zwraca prawde jezeli dalo sie scalic } bool mergesort(int low, int high) { //rekurencyjne dzielenie zbioru na 2 podzbiory do uzyskania zbioru 1-elementowego //wtedy scalenie dwóch zbiorów w jeden posortowany if(low>=high) return true; int mid=(low+high)/2; return (mergesort(low, mid) && mergesort(mid+1, high) && merge(low, high)); } int main() { scanf("%d", &test); for(int t=0; t<test; t++) { scanf("%d%d", &qt, &height); for(int i=0; i<qt; i++) { scanf("%d%d%d%d", &(tab[i].bx1), &(tab[i].by1), &(tab[i].bx2), &(tab[i].by2)); if(tab[i].bx1 > tab[i].bx2) swap(tab[i].bx1, tab[i].bx2); if(tab[i].by1 > tab[i].by2) swap(tab[i].by1, tab[i].by2); tab[i].height = tab[i].by2 - tab[i].by1; } for(int i=0; i<qt; i++) { scanf("%d%d%d%d", &(tab[i].ex1), &(tab[i].ey1), &(tab[i].ex2), &(tab[i].ey2)); if(tab[i].ex1 > tab[i].ex2) swap(tab[i].ex1, tab[i].ex2); if(tab[i].ey1 > tab[i].ey2) swap(tab[i].ey1, tab[i].ey2); } sort(tab, tab+qt, CmpEnd); for(int i=0; i<qt; i++){ tab[i].end_num = i;} sort(tab, tab+qt, CmpBeg); if(mergesort(0, qt-1)) printf("TAK\n"); else printf("NIE\n"); } } |