#include <bits/stdc++.h> using namespace std; typedef long long int LL; const int N = 2007; const int inf = 2e9 + 7; int n; int ans[N]; pair <pair <int, int>, int> tab[N]; bool cmp(pair <pair <int, int>, int> a, pair <pair <int, int>, int> b){ if(a.first.second == b.first.second) return a.first.first < b.first.first; return a.first.second < b.first.second; } void write(LL res, int mnX, int mxX, int mnY, int mxY){ if(res == 1LL * (mxX - mnX + 1) * (mxY - mnY + 1)){ printf("TAK "); for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); } else puts("NIE"); } void solve(){ scanf("%d", &n); for(int i = 1; i <= n; ++i){ scanf("%d %d", &tab[i].first.first, &tab[i].first.second); tab[i].second = i; } if(n == 1){ puts("TAK 1"); return; } vector <int> otoczka; sort(tab + 1, tab + n + 1, cmp); LL res = 0LL; int mxX = 0, mxY = 0; int mnX = inf, mnY = inf; for(int i = 1; i <= n; ++i){ int limit = inf; if(i < n && tab[i + 1].first.second == tab[i].first.second) limit = tab[i + 1].first.first - tab[i].first.first; for(int j = 1; j < i; ++j) if(ans[tab[j].second] < inf && tab[j].first.second + ans[tab[j].second] > tab[i].first.second && tab[j].first.first >= tab[i].first.first) limit = min(limit, tab[j].first.first - tab[i].first.first); if(limit == inf) otoczka.push_back(i); else{ for(int j = i + 1; j <= n; ++j) if(tab[j].first.first >= tab[i].first.first && max(tab[j].first.first - tab[i].first.first, tab[j].first.second - tab[i].first.second) < limit){ puts("NIE"); return; } } ans[tab[i].second] = limit; if(limit < inf) res += 1LL * limit * limit; if(limit < inf){ mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } } // for(int i = 1; i <= n; ++ i) // printf("%d ", ans[tab[i].second]); // puts(""); int last = -1; vector <int> xd; for(int i = otoczka.size() - 1; i >= 0; --i){ int u = otoczka[i]; if(tab[u].first.first > last){ last = tab[u].first.first; xd.push_back(u); continue; } for(int j = i + 1; j < (int)otoczka.size(); ++j){ int v = otoczka[j]; if(ans[tab[v].second] == inf && tab[v].first.first >= tab[u].first.first) ans[tab[u].second] = min(ans[tab[u].second], max(tab[v].first.second - tab[u].first.second, tab[v].first.first - tab[u].first.first)); else if(tab[v].first.first + ans[tab[v].second] > tab[u].first.first) ans[tab[u].second] = min(ans[tab[u].second], tab[v].first.second - tab[u].first.second); } for(int j = 1; j <= n; ++j){ if(ans[tab[j].second] != inf && tab[j].first.first + ans[tab[j].second] > tab[u].first.first && tab[j].first.second > tab[u].first.second) ans[tab[u].second] = min(ans[tab[u].second], max(tab[j].first.second - tab[u].first.second, tab[j].first.first - tab[u].first.first)); } res += 1LL * ans[tab[u].second] * ans[tab[u].second]; mnX = min(mnX, tab[u].first.first); mnY = min(mnY, tab[u].first.second); mxX = max(mxX, tab[u].first.first + ans[tab[u].second] - 1); mxY = max(mxY, tab[u].first.second + ans[tab[u].second] - 1); } // for(int i = 1; i <= n; ++i) // printf("%d ", ans[tab[i].second]); otoczka = xd; if(otoczka.size() == 0){ write(res, mnX, mxX, mnY, mxY); return; } reverse(otoczka.begin(), otoczka.end()); if(tab[otoczka[0]].first.second > mnY){ for(int i: otoczka){ int limit = mxX - tab[i].first.first + 1; for(int j: otoczka){ if(i == j) break; if(tab[j].first.second + ans[tab[j].second] > tab[i].first.second) limit = min(limit, tab[j].first.first - tab[i].first.first); } ans[tab[i].second] = limit; res += 1LL * limit * limit; mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } write(res, mnX, mxX, mnY, mxY); return; } if(tab[otoczka[otoczka.size() - 1]].first.second <= mxY){ reverse(otoczka.begin(), otoczka.end()); for(int i: otoczka){ int limit = mxY - tab[i].first.second + 1; for(int j: otoczka){ if(i == j) break; if(tab[j].first.first + ans[tab[j].second] > tab[i].first.first) limit = min(limit, tab[j].first.second - tab[i].first.second); } ans[tab[i].second] = limit; res += 1LL * limit * limit; mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } write(res, mnX, mxX, mnY, mxY); return; } int help = tab[otoczka[0]].first.first; { LL res2 = res; for(int i: otoczka){ if(i == otoczka[0]) continue; int limit = help - tab[i].first.first; for(int j: otoczka){ if(j == otoczka[0]) continue; if(i == j) break; if(tab[j].first.second + ans[tab[j].second] > tab[i].first.second) limit = min(limit, tab[j].first.first - tab[i].first.first); } ans[i] = limit; res2 += 1LL * limit * limit; help = max(help, tab[i].first.second + ans[tab[i].second] - 1); } if(res2 == 1LL * (mxX - mnX + 1) * (help - mnY + 1)){ printf("TAK "); ans[tab[otoczka[0]].second] = help - mnY + 1; for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); return; } } reverse(otoczka.begin(), otoczka.end()); help = tab[otoczka[0]].first.second; { LL res2 = res; for(int i: otoczka){ if(i == otoczka[0]) continue; int limit = help - tab[i].first.second; for(int j: otoczka){ if(j == otoczka[0]) continue; if(i == j) break; if(tab[j].first.first + ans[tab[j].second] > tab[i].first.first) limit = min(limit, tab[j].first.second - tab[i].first.second); } ans[i] = limit; res2 += 1LL * limit * limit; help = max(help, tab[i].first.first + ans[tab[i].second] - 1); } if(res2 == 1LL * (mxX - mnX + 1) * (help - mnY + 1)){ printf("TAK "); ans[tab[otoczka[0]].second] = help - mnX + 1; for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); return; } } puts("NIE"); } int main(){ int quest; scanf("%d", &quest); while(quest--) solve(); 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 | #include <bits/stdc++.h> using namespace std; typedef long long int LL; const int N = 2007; const int inf = 2e9 + 7; int n; int ans[N]; pair <pair <int, int>, int> tab[N]; bool cmp(pair <pair <int, int>, int> a, pair <pair <int, int>, int> b){ if(a.first.second == b.first.second) return a.first.first < b.first.first; return a.first.second < b.first.second; } void write(LL res, int mnX, int mxX, int mnY, int mxY){ if(res == 1LL * (mxX - mnX + 1) * (mxY - mnY + 1)){ printf("TAK "); for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); } else puts("NIE"); } void solve(){ scanf("%d", &n); for(int i = 1; i <= n; ++i){ scanf("%d %d", &tab[i].first.first, &tab[i].first.second); tab[i].second = i; } if(n == 1){ puts("TAK 1"); return; } vector <int> otoczka; sort(tab + 1, tab + n + 1, cmp); LL res = 0LL; int mxX = 0, mxY = 0; int mnX = inf, mnY = inf; for(int i = 1; i <= n; ++i){ int limit = inf; if(i < n && tab[i + 1].first.second == tab[i].first.second) limit = tab[i + 1].first.first - tab[i].first.first; for(int j = 1; j < i; ++j) if(ans[tab[j].second] < inf && tab[j].first.second + ans[tab[j].second] > tab[i].first.second && tab[j].first.first >= tab[i].first.first) limit = min(limit, tab[j].first.first - tab[i].first.first); if(limit == inf) otoczka.push_back(i); else{ for(int j = i + 1; j <= n; ++j) if(tab[j].first.first >= tab[i].first.first && max(tab[j].first.first - tab[i].first.first, tab[j].first.second - tab[i].first.second) < limit){ puts("NIE"); return; } } ans[tab[i].second] = limit; if(limit < inf) res += 1LL * limit * limit; if(limit < inf){ mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } } // for(int i = 1; i <= n; ++ i) // printf("%d ", ans[tab[i].second]); // puts(""); int last = -1; vector <int> xd; for(int i = otoczka.size() - 1; i >= 0; --i){ int u = otoczka[i]; if(tab[u].first.first > last){ last = tab[u].first.first; xd.push_back(u); continue; } for(int j = i + 1; j < (int)otoczka.size(); ++j){ int v = otoczka[j]; if(ans[tab[v].second] == inf && tab[v].first.first >= tab[u].first.first) ans[tab[u].second] = min(ans[tab[u].second], max(tab[v].first.second - tab[u].first.second, tab[v].first.first - tab[u].first.first)); else if(tab[v].first.first + ans[tab[v].second] > tab[u].first.first) ans[tab[u].second] = min(ans[tab[u].second], tab[v].first.second - tab[u].first.second); } for(int j = 1; j <= n; ++j){ if(ans[tab[j].second] != inf && tab[j].first.first + ans[tab[j].second] > tab[u].first.first && tab[j].first.second > tab[u].first.second) ans[tab[u].second] = min(ans[tab[u].second], max(tab[j].first.second - tab[u].first.second, tab[j].first.first - tab[u].first.first)); } res += 1LL * ans[tab[u].second] * ans[tab[u].second]; mnX = min(mnX, tab[u].first.first); mnY = min(mnY, tab[u].first.second); mxX = max(mxX, tab[u].first.first + ans[tab[u].second] - 1); mxY = max(mxY, tab[u].first.second + ans[tab[u].second] - 1); } // for(int i = 1; i <= n; ++i) // printf("%d ", ans[tab[i].second]); otoczka = xd; if(otoczka.size() == 0){ write(res, mnX, mxX, mnY, mxY); return; } reverse(otoczka.begin(), otoczka.end()); if(tab[otoczka[0]].first.second > mnY){ for(int i: otoczka){ int limit = mxX - tab[i].first.first + 1; for(int j: otoczka){ if(i == j) break; if(tab[j].first.second + ans[tab[j].second] > tab[i].first.second) limit = min(limit, tab[j].first.first - tab[i].first.first); } ans[tab[i].second] = limit; res += 1LL * limit * limit; mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } write(res, mnX, mxX, mnY, mxY); return; } if(tab[otoczka[otoczka.size() - 1]].first.second <= mxY){ reverse(otoczka.begin(), otoczka.end()); for(int i: otoczka){ int limit = mxY - tab[i].first.second + 1; for(int j: otoczka){ if(i == j) break; if(tab[j].first.first + ans[tab[j].second] > tab[i].first.first) limit = min(limit, tab[j].first.second - tab[i].first.second); } ans[tab[i].second] = limit; res += 1LL * limit * limit; mnX = min(mnX, tab[i].first.first); mnY = min(mnY, tab[i].first.second); mxX = max(mxX, tab[i].first.first + ans[tab[i].second] - 1); mxY = max(mxY, tab[i].first.second + ans[tab[i].second] - 1); } write(res, mnX, mxX, mnY, mxY); return; } int help = tab[otoczka[0]].first.first; { LL res2 = res; for(int i: otoczka){ if(i == otoczka[0]) continue; int limit = help - tab[i].first.first; for(int j: otoczka){ if(j == otoczka[0]) continue; if(i == j) break; if(tab[j].first.second + ans[tab[j].second] > tab[i].first.second) limit = min(limit, tab[j].first.first - tab[i].first.first); } ans[i] = limit; res2 += 1LL * limit * limit; help = max(help, tab[i].first.second + ans[tab[i].second] - 1); } if(res2 == 1LL * (mxX - mnX + 1) * (help - mnY + 1)){ printf("TAK "); ans[tab[otoczka[0]].second] = help - mnY + 1; for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); return; } } reverse(otoczka.begin(), otoczka.end()); help = tab[otoczka[0]].first.second; { LL res2 = res; for(int i: otoczka){ if(i == otoczka[0]) continue; int limit = help - tab[i].first.second; for(int j: otoczka){ if(j == otoczka[0]) continue; if(i == j) break; if(tab[j].first.first + ans[tab[j].second] > tab[i].first.first) limit = min(limit, tab[j].first.second - tab[i].first.second); } ans[i] = limit; res2 += 1LL * limit * limit; help = max(help, tab[i].first.first + ans[tab[i].second] - 1); } if(res2 == 1LL * (mxX - mnX + 1) * (help - mnY + 1)){ printf("TAK "); ans[tab[otoczka[0]].second] = help - mnX + 1; for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); return; } } puts("NIE"); } int main(){ int quest; scanf("%d", &quest); while(quest--) solve(); return 0; } |