/************************************************************************* * Zadanie: Parking * * Zlozonosc czasowa: O(tn log n) * * Wynik: --/10 * *************************************************************************/ #include <iostream> #include <vector> #include <algorithm> #define FOR(i,b,e) for(int i=(b); i <= (e); ++i) #define FORD(i,b,e) for(int i=(b); i >= (e); --i) #define SIZE(c) (int) (c).size() #define FOREACH(i,c) FOR(i,0,SIZE(c)-1) #define FORDEACH(i,c) FORD(i,SIZE(c)-1,0) #define MAX(x,y) ( ((x) > (y))? (x) : (y) ) #define PB push_back using namespace std; struct car { int id; int x; int y; car(int c_id, int c_x, int c_y) { id = c_id; x = c_x; y = c_y; } }; bool comp(car a, car b) { return ((a.x == b.x)? (a.y < b.y) : (a.x < b.x)); } int w; vector < int > pos; //pozycja kazdego id w posortowanym V[1] vector < int > H; //wysokosc kazdego auta po id bool merge_comp(int a, int b) { return (pos[a] < pos[b]); } bool mergesort(vector < int > &M) { int s = SIZE(M); if (s < 2) return 1; vector < int > M1, M2; M1.assign(M.begin(),M.begin() + s/2); M2.assign(M.begin() + s/2,M.end()); bool b1 = mergesort(M1), b2 = mergesort(M2); if (!b1 || !b2) return 0; //pomocniczo maxy H sufiksow M1: vector < int > MAX1(SIZE(M1)); MAX1.back() = H[M1.back()]; FORD(i,SIZE(MAX1)-2,0) MAX1[i] = MAX(MAX1[i+1],H[M1[i]]); //merge M1 i M2: int it1 = 0, it2 = 0, i = 0; //indeksy po M1, M2, M while (it1 < SIZE(M1) && it2 < SIZE(M2)) { int v1 = M1[it1], v2 = M2[it2]; if (merge_comp(v1,v2)) M[i++] = M1[it1++]; else { if (H[v2] + MAX1[it1] > w) return 0; M[i++] = M2[it2++]; } } while (it1 < SIZE(M1)) M[i++] = M1[it1++]; while (it2 < SIZE(M2)) M[i++] = M2[it2++]; return 1; } /*************************************************************************/ int main() { ios_base::sync_with_stdio(0); int t; cin >> t; while (t--) { int n; cin >> n >> w; vector < car > V[2]; //V[0] - pozycja wyjsciowa, V[1] - koncowa H.resize(n); FOR(p,0,1) { FOR(i,0,n-1) { int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; if (x1 > x2) swap(x1,x2); if (y1 > y2) swap(y1,y2); V[p].PB( car(i,x1,y1) ); H[i] = y2-y1; } sort(V[p].begin(), V[p].end(), comp); } pos.resize(n); FOREACH(i,V[1]) pos[V[1][i].id] = i; vector < int > M(n); FOREACH(i,M) M[i] = V[0][i].id; bool ans = mergesort(M); cout << ((ans)? "TAK" : "NIE") << '\n'; } return 0; } /*************************************************************************/
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | /************************************************************************* * Zadanie: Parking * * Zlozonosc czasowa: O(tn log n) * * Wynik: --/10 * *************************************************************************/ #include <iostream> #include <vector> #include <algorithm> #define FOR(i,b,e) for(int i=(b); i <= (e); ++i) #define FORD(i,b,e) for(int i=(b); i >= (e); --i) #define SIZE(c) (int) (c).size() #define FOREACH(i,c) FOR(i,0,SIZE(c)-1) #define FORDEACH(i,c) FORD(i,SIZE(c)-1,0) #define MAX(x,y) ( ((x) > (y))? (x) : (y) ) #define PB push_back using namespace std; struct car { int id; int x; int y; car(int c_id, int c_x, int c_y) { id = c_id; x = c_x; y = c_y; } }; bool comp(car a, car b) { return ((a.x == b.x)? (a.y < b.y) : (a.x < b.x)); } int w; vector < int > pos; //pozycja kazdego id w posortowanym V[1] vector < int > H; //wysokosc kazdego auta po id bool merge_comp(int a, int b) { return (pos[a] < pos[b]); } bool mergesort(vector < int > &M) { int s = SIZE(M); if (s < 2) return 1; vector < int > M1, M2; M1.assign(M.begin(),M.begin() + s/2); M2.assign(M.begin() + s/2,M.end()); bool b1 = mergesort(M1), b2 = mergesort(M2); if (!b1 || !b2) return 0; //pomocniczo maxy H sufiksow M1: vector < int > MAX1(SIZE(M1)); MAX1.back() = H[M1.back()]; FORD(i,SIZE(MAX1)-2,0) MAX1[i] = MAX(MAX1[i+1],H[M1[i]]); //merge M1 i M2: int it1 = 0, it2 = 0, i = 0; //indeksy po M1, M2, M while (it1 < SIZE(M1) && it2 < SIZE(M2)) { int v1 = M1[it1], v2 = M2[it2]; if (merge_comp(v1,v2)) M[i++] = M1[it1++]; else { if (H[v2] + MAX1[it1] > w) return 0; M[i++] = M2[it2++]; } } while (it1 < SIZE(M1)) M[i++] = M1[it1++]; while (it2 < SIZE(M2)) M[i++] = M2[it2++]; return 1; } /*************************************************************************/ int main() { ios_base::sync_with_stdio(0); int t; cin >> t; while (t--) { int n; cin >> n >> w; vector < car > V[2]; //V[0] - pozycja wyjsciowa, V[1] - koncowa H.resize(n); FOR(p,0,1) { FOR(i,0,n-1) { int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; if (x1 > x2) swap(x1,x2); if (y1 > y2) swap(y1,y2); V[p].PB( car(i,x1,y1) ); H[i] = y2-y1; } sort(V[p].begin(), V[p].end(), comp); } pos.resize(n); FOREACH(i,V[1]) pos[V[1][i].id] = i; vector < int > M(n); FOREACH(i,M) M[i] = V[0][i].id; bool ans = mergesort(M); cout << ((ans)? "TAK" : "NIE") << '\n'; } return 0; } /*************************************************************************/ |