#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <set> using namespace std; bool rozwiazanie; long long t, n, poz, a, b, ile, koniec, poczatek, dlugosc, wyn; pair <long long, long long> punkty[2005]; pair <long long, long long> odw[2005]; long long wynik[2005]; pair < pair <long long, long long>, long long > sortowanie[2005]; vector <long long> konce; vector < pair <long long, long long> > P; vector < pair <long long, long long> > v; vector < pair <long long, long long> >::iterator it, it2; set < pair <long long, pair <long long, long long> > > znika; set < pair <long long, pair <long long, long long> > >::iterator zit; set < pair <long long, long long > > przedzialy; set < pair <long long, long long > >::iterator sit; int main () { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d%d", &punkty[i].first, &punkty[i].second); sortowanie[i].first.first = punkty[i].first; sortowanie[i].first.second = punkty[i].second; sortowanie[i].second = i; } sort(sortowanie, sortowanie + n); sort(punkty, punkty + n); rozwiazanie = 1; for (int i = 0; i < n; ++i) if (punkty[i].second < punkty[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } if (n == 1) { printf("TAK 1\n"); continue; } if (n == 2) { if (punkty[0].first == punkty[1].first) { wyn = punkty[1].second - punkty[0].second; printf("TAK %lld %lld\n", wyn, wyn); } else if (punkty[0].second == punkty[1].second) { wyn = punkty[1].first - punkty[0].first; printf("TAK %lld %lld\n", wyn, wyn); } else printf("NIE\n"); continue; } for (int i = 0; i < n; ++i) { odw[i].first = punkty[i].second; odw[i].second = punkty[i].first; } sort(odw, odw + n); v.clear(); for (int i = 0; i < n; ++i) v.push_back(odw[i]); P.clear(); for (int i = 0; i < n; ++i) P.push_back(punkty[i]); if (punkty[n - 1].first == punkty[0].first) { for (int i = 1; i < n; ++i) if (punkty[i].second - punkty[i - 1].second != punkty[1].second - punkty[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } printf("TAK"); for (int i = 0; i < n; ++i) { wyn = punkty[1].second - punkty[0].second; printf(" %lld", wyn); } printf("\n"); continue; } if (odw[n - 1].first == odw[0].first) { for (int i = 1; i < n; ++i) if (odw[i].second - odw[i - 1].second != odw[1].second - odw[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } printf("TAK"); for (int i = 0; i < n; ++i) { wyn = odw[1].second - odw[0].second; printf(" %lld", wyn); } printf("\n"); continue; } poz = 0; while (punkty[poz].first == punkty[0].first) poz++; poz--; konce.clear(); if (poz == 0) konce.push_back(odw[1].second - odw[0].second + punkty[0].second); else { a = punkty[poz].first; b = punkty[poz].second; it = upper_bound(v.begin(), v.end(), make_pair(b, a)); if (it != v.end() && it->first == b && it->second - a <= b - punkty[poz - 1].second) konce.push_back(it->second - a + b); else { a += b - punkty[poz - 1].second; konce.push_back(b - punkty[poz - 1].second + b); while (1) { it = lower_bound(P.begin(), P.end(), make_pair(a, b)); it--; if (it->first != a) break; it2 = upper_bound(v.begin(), v.end(), make_pair(b, a)); if (it2 != v.end() && it2->first == b && it2->second - a <= b - it->second) { konce.push_back(b + it2->second - punkty[poz].first); break; } a += b - it->second; konce.push_back(a - punkty[poz].first + b); } } } ile = konce.size(); poczatek = punkty[0].second; for (int i = 0; i < ile; ++i) { rozwiazanie = 1; znika.clear(); przedzialy.clear(); przedzialy.insert(make_pair(poczatek - 1, poczatek)); koniec = konce[i]; przedzialy.insert(make_pair(koniec, koniec + 1)); for (int j = 0; j < n; ++j) if (punkty[j].second >= koniec) { rozwiazanie = 0; break; } if (rozwiazanie == 0) continue; for (int j = 0; j < poz; ++j) { znika.insert(make_pair(punkty[0].first + punkty[j + 1].second - punkty[j].second, make_pair(punkty[j].second, punkty[j + 1].second))); wynik[sortowanie[j].second] = punkty[j + 1].second - punkty[j].second; przedzialy.insert(make_pair(punkty[j].second, punkty[j + 1].second)); } znika.insert(make_pair(koniec - punkty[poz].second + punkty[0].first, make_pair(punkty[poz].second, koniec))); wynik[sortowanie[poz].second] = koniec - punkty[poz].second; przedzialy.insert(make_pair(punkty[poz].second, koniec)); dlugosc = koniec - poczatek; for (int j = poz + 1; j < n; ++j) { if (znika.begin()->first < punkty[j].first) { rozwiazanie = 0; break; } while (!znika.empty() && znika.begin()->first == punkty[j].first) { przedzialy.erase(make_pair(znika.begin()->second.first, znika.begin()->second.second)); dlugosc -= znika.begin()->second.second - znika.begin()->second.first; znika.erase(znika.begin()); } sit = przedzialy.upper_bound(make_pair(punkty[j].second, punkty[j].second)); if (sit->first == punkty[j].second) { rozwiazanie = 0; break; } sit--; if (sit->second != punkty[j].second) { rozwiazanie = 0; break; } sit++; if (j == n - 1 || punkty[j + 1].first != punkty[j].first || punkty[j + 1].second >= sit->first) { wynik[sortowanie[j].second] = sit->first - punkty[j].second; dlugosc += wynik[sortowanie[j].second]; przedzialy.insert(make_pair(punkty[j].second, sit->first)); znika.insert(make_pair(punkty[j].first + sit->first - punkty[j].second, make_pair(punkty[j].second, sit->first))); } else { wynik[sortowanie[j].second] = punkty[j + 1].second - punkty[j].second; dlugosc += wynik[sortowanie[j].second]; przedzialy.insert(make_pair(punkty[j].second, punkty[j + 1].second)); znika.insert(make_pair(punkty[j].first + punkty[j + 1].second - punkty[j].second, make_pair(punkty[j].second, punkty[j + 1].second))); } if (j == n - 1 || punkty[j + 1].first != punkty[j].first) { if (dlugosc != koniec - poczatek) { rozwiazanie = 0; break; } } } if (rozwiazanie == 0) continue; zit = znika.end(); zit--; if (zit->first != znika.begin()->first) { rozwiazanie = 0; continue; } printf("TAK"); for (int j = 0; j < n; ++j) printf(" %lld", wynik[j]); printf("\n"); break; } if (rozwiazanie == 0) printf("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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <set> using namespace std; bool rozwiazanie; long long t, n, poz, a, b, ile, koniec, poczatek, dlugosc, wyn; pair <long long, long long> punkty[2005]; pair <long long, long long> odw[2005]; long long wynik[2005]; pair < pair <long long, long long>, long long > sortowanie[2005]; vector <long long> konce; vector < pair <long long, long long> > P; vector < pair <long long, long long> > v; vector < pair <long long, long long> >::iterator it, it2; set < pair <long long, pair <long long, long long> > > znika; set < pair <long long, pair <long long, long long> > >::iterator zit; set < pair <long long, long long > > przedzialy; set < pair <long long, long long > >::iterator sit; int main () { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d%d", &punkty[i].first, &punkty[i].second); sortowanie[i].first.first = punkty[i].first; sortowanie[i].first.second = punkty[i].second; sortowanie[i].second = i; } sort(sortowanie, sortowanie + n); sort(punkty, punkty + n); rozwiazanie = 1; for (int i = 0; i < n; ++i) if (punkty[i].second < punkty[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } if (n == 1) { printf("TAK 1\n"); continue; } if (n == 2) { if (punkty[0].first == punkty[1].first) { wyn = punkty[1].second - punkty[0].second; printf("TAK %lld %lld\n", wyn, wyn); } else if (punkty[0].second == punkty[1].second) { wyn = punkty[1].first - punkty[0].first; printf("TAK %lld %lld\n", wyn, wyn); } else printf("NIE\n"); continue; } for (int i = 0; i < n; ++i) { odw[i].first = punkty[i].second; odw[i].second = punkty[i].first; } sort(odw, odw + n); v.clear(); for (int i = 0; i < n; ++i) v.push_back(odw[i]); P.clear(); for (int i = 0; i < n; ++i) P.push_back(punkty[i]); if (punkty[n - 1].first == punkty[0].first) { for (int i = 1; i < n; ++i) if (punkty[i].second - punkty[i - 1].second != punkty[1].second - punkty[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } printf("TAK"); for (int i = 0; i < n; ++i) { wyn = punkty[1].second - punkty[0].second; printf(" %lld", wyn); } printf("\n"); continue; } if (odw[n - 1].first == odw[0].first) { for (int i = 1; i < n; ++i) if (odw[i].second - odw[i - 1].second != odw[1].second - odw[0].second) rozwiazanie = 0; if (rozwiazanie == 0) { printf("NIE\n"); continue; } printf("TAK"); for (int i = 0; i < n; ++i) { wyn = odw[1].second - odw[0].second; printf(" %lld", wyn); } printf("\n"); continue; } poz = 0; while (punkty[poz].first == punkty[0].first) poz++; poz--; konce.clear(); if (poz == 0) konce.push_back(odw[1].second - odw[0].second + punkty[0].second); else { a = punkty[poz].first; b = punkty[poz].second; it = upper_bound(v.begin(), v.end(), make_pair(b, a)); if (it != v.end() && it->first == b && it->second - a <= b - punkty[poz - 1].second) konce.push_back(it->second - a + b); else { a += b - punkty[poz - 1].second; konce.push_back(b - punkty[poz - 1].second + b); while (1) { it = lower_bound(P.begin(), P.end(), make_pair(a, b)); it--; if (it->first != a) break; it2 = upper_bound(v.begin(), v.end(), make_pair(b, a)); if (it2 != v.end() && it2->first == b && it2->second - a <= b - it->second) { konce.push_back(b + it2->second - punkty[poz].first); break; } a += b - it->second; konce.push_back(a - punkty[poz].first + b); } } } ile = konce.size(); poczatek = punkty[0].second; for (int i = 0; i < ile; ++i) { rozwiazanie = 1; znika.clear(); przedzialy.clear(); przedzialy.insert(make_pair(poczatek - 1, poczatek)); koniec = konce[i]; przedzialy.insert(make_pair(koniec, koniec + 1)); for (int j = 0; j < n; ++j) if (punkty[j].second >= koniec) { rozwiazanie = 0; break; } if (rozwiazanie == 0) continue; for (int j = 0; j < poz; ++j) { znika.insert(make_pair(punkty[0].first + punkty[j + 1].second - punkty[j].second, make_pair(punkty[j].second, punkty[j + 1].second))); wynik[sortowanie[j].second] = punkty[j + 1].second - punkty[j].second; przedzialy.insert(make_pair(punkty[j].second, punkty[j + 1].second)); } znika.insert(make_pair(koniec - punkty[poz].second + punkty[0].first, make_pair(punkty[poz].second, koniec))); wynik[sortowanie[poz].second] = koniec - punkty[poz].second; przedzialy.insert(make_pair(punkty[poz].second, koniec)); dlugosc = koniec - poczatek; for (int j = poz + 1; j < n; ++j) { if (znika.begin()->first < punkty[j].first) { rozwiazanie = 0; break; } while (!znika.empty() && znika.begin()->first == punkty[j].first) { przedzialy.erase(make_pair(znika.begin()->second.first, znika.begin()->second.second)); dlugosc -= znika.begin()->second.second - znika.begin()->second.first; znika.erase(znika.begin()); } sit = przedzialy.upper_bound(make_pair(punkty[j].second, punkty[j].second)); if (sit->first == punkty[j].second) { rozwiazanie = 0; break; } sit--; if (sit->second != punkty[j].second) { rozwiazanie = 0; break; } sit++; if (j == n - 1 || punkty[j + 1].first != punkty[j].first || punkty[j + 1].second >= sit->first) { wynik[sortowanie[j].second] = sit->first - punkty[j].second; dlugosc += wynik[sortowanie[j].second]; przedzialy.insert(make_pair(punkty[j].second, sit->first)); znika.insert(make_pair(punkty[j].first + sit->first - punkty[j].second, make_pair(punkty[j].second, sit->first))); } else { wynik[sortowanie[j].second] = punkty[j + 1].second - punkty[j].second; dlugosc += wynik[sortowanie[j].second]; przedzialy.insert(make_pair(punkty[j].second, punkty[j + 1].second)); znika.insert(make_pair(punkty[j].first + punkty[j + 1].second - punkty[j].second, make_pair(punkty[j].second, punkty[j + 1].second))); } if (j == n - 1 || punkty[j + 1].first != punkty[j].first) { if (dlugosc != koniec - poczatek) { rozwiazanie = 0; break; } } } if (rozwiazanie == 0) continue; zit = znika.end(); zit--; if (zit->first != znika.begin()->first) { rozwiazanie = 0; continue; } printf("TAK"); for (int j = 0; j < n; ++j) printf(" %lld", wynik[j]); printf("\n"); break; } if (rozwiazanie == 0) printf("NIE\n"); } return 0; } |