#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; } |
English