1103 - Harta
Pe baza unei imagini preluate din satelit, se realizează harta unei mici localități. Localitatea ocupă o suprafață dreptunghiulară, cu laturile orientate pe direcțiile Nord-Sud, respectiv Est-Vest. Studiind imaginea obținută de la satelit, cartografii au constatat că toate cele k
clădiri au forma unor dreptunghiuri distincte. Imaginea poate fi reprezentată sub forma unui tablou cu n•m
celule așezate pe n
linii numerotate de la 1
la n
și m
coloane numerotate de la 1
la m
.
Numim drum, un dreptunghi al tabloului care străbate întreaga localitate pe direcția Est-Vest și are un număr maxim de linii sau un dreptunghi care străbate întreaga localitate pe direcția Nord-Sud și are un număr maxim de coloane. Drumurile, evident, nu trebuie să treacă prin clădiri.
Cartografii sunt interesați ca pe această hartă să fie reprezentate la scară doar clădirile, nu și drumurile. De aceea, pentru realizarea hărții, lățimile drumurilor au fost reduse la o singură celulă
Tabloul care reprezintă imaginea localității se codifică astfel: 1
pentru o celulă ocupată de o clădire și 0
pentru o celulă neocupată.
Cerinţe[edit | edit source]
Cunoscând n
, m
și k
, precum și tabloul care codifică imaginea, se cere să se determine:
1. Numărul S
de celule ocupate de către clădirea pătratică cu latura maximă și numărul de clădiri C
alese dintre celelalte k – 1
clădiri, cu proprietatea că fiecare dintre ele “încape” în interiorul clădirii pătratice cu latură maximă, fără să se suprapună peste celulele marginale ale acesteia.
2. Tabloul care reprezintă harta, în urma prelucrării imaginii inițiale.
Date de intrare[edit | edit source]
Fişierul de intrare harta.in
conţine pe prima linie un număr natural p
. Pentru toate testele de intrare, numărul p
poate avea doar valoarea 1
sau valoarea 2
.
Pe linia a doua se găsesc numerele naturale n
, m
și k
separate prin câte un spațiu.
Pe fiecare dintre următoarele k
linii, se găsesc câte patru numere naturale i1 j1 i2 j2
separate prin câte un spațiu, primele două numere reprezentând coordonatele celulei din extremitatea Nord-Vest, iar ultimele două, coordonatele celulei din extremitatea Sud-Est pentru fiecare dintre cele k
clădiri.
Date de ieșire[edit | edit source]
- Dacă valoarea lui
p
este1
, atunci se va rezolva numai cerința1
. În acest caz, în fişierul de ieşireharta.out
se vor scrie cele două numereS
șiC
având semnificația descrisă la cerința1
, separate printr-un singur spațiu. - Dacă valoarea lui
p
este2
, atunci se va rezolva numai cerința2
. În acest caz, fişierul de ieşireharta.out
va conține tabloul care reprezintă harta obținută pe baza imaginii din satelit. Fișierul va avean1
linii. Pe fiecare linie se vor găsi câtem1
valori0
sau1
separate prin câte un singur spațiu. Celulele situate pe marginile clădirilor vor avea valoarea1
. Celulele din interiorul clădirilor, ca și cele din exterior, vor avea valoarea0
.
Restricții și precizări[edit | edit source]
3 ≤ n, m ≤ 1500
1 ≤ i1 ≤ i2 ≤ n
1 ≤ j1 ≤ j2 ≤ m
1 ≤ k ≤ 1000
1 ≤ Lmax ≤ 50
(Lmax
– latura maximă a unui dreptunghi)- Se garantează că există soluție pentru ambele cerințe, pentru toate datele de test.
- Pentru rezolvarea corectă a primei cerinţe se acordă 20 de puncte, iar pentru cerința a doua se acordă 80 de puncte.
Exemplul 1[edit | edit source]
harta.in
1 7 7 4 1 1 4 4 6 2 6 4 3 6 3 6 6 6 7 7
harta.out
16 2
Încărcare soluție[edit | edit source]
Lipește codul aici[edit | edit source]
<syntaxhighlight lang="python" line="1"> import numpy as np
- define pb push_back
- define DIM 1501
typedef vector<int> VI;
d = [] xa = [] ya = [] x = [0] y = [0] s1 = [True] s2 = [True] c1 = [] c2 = [] b1 = [] b2 = [] k = 0 N = 0 M = 0 n = 0 m = 0 Lmax = 0 L = 0 H = 0 T = 0 nr_dr = 0 A = np.zeros((1501, 1501), dtype=bool)
def GetPos(v, val):
n = len(v) lo = 0 hi = n while lo <= hi: mid = lo + (hi - lo) // 2 if v[mid] == val: return mid if val < v[mid]: hi = mid - 1 else: lo = mid + 1 return 0
def WriteMatr(a, N, M):
for i in range(1, N+1): for j in range(1, M+1): fout.write(str(int(a[i][j])) + ' ') fout.write('\n')
with open("harta.in", "r") as fin:
lines = fin.readlines() T, N, M, k = map(int, lines[0].split()) imax = 0 jmax = 0 for i in range(k): i1, j1, i2, j2 = map(int, lines[i+1].split()) d.append((i1, j1, i2, j2)) L = i2 - i1 + 1 H = j2 - j1 + 1 if L == H and L > Lmax: Lmax = L for i in range(i1, i2+1): xa.extend([i, i]) ya.extend([j1, j2]) if not s1[i]: x.append(i) s1[i] = True for j in range(j1, j2+1): xa.extend([i1, i2]) ya.extend([j, j]) if not s2[j]: y.append(j) s2[j] = True if not s1[i1 - 1]: x.append(i1 - 1) s1[i1 - 1] = True if not s2[j1 - 1]: y.append(j1 - 1) s2[j1 - 1] = True imax = max(imax, i2) jmax = max(jmax, j2) if T == 1: for i in range(k): L = d[i][2] - d[i][0] + 1 H = d[i][3] - d[i][1] + 1 if L < Lmax - 1 and H < Lmax - 1: nr_dr += 1 fout.write(str(Lmax * Lmax) + ' ' + str(nr_dr) + '\n') else: c1 = [0] * (imax + 1) c2 = [0] * (jmax + 1) for i in range(len(x)): c1[x[i]] += 1 for i in range(len(y)): c2[y[i]] += 1 for i in range(1, imax+1): c1[i] += c1[i - 1] for i in range(1, jmax+1): c2[i] += c2[i - 1] b1 = [0] * len(x) b2 = [0] * len(y) for i in range(len(x)): b1[c1[x[i]] - 1] = x[i] c1[x[i]] -= 1 for i in range(len(y)): b2[c2[y[i]] - 1] = y[i] c2[y[i]] -= 1 n = 0 m = 0 for k in range(len(xa)): i = GetPos(b1, xa[k]) j = GetPos(b2, ya[k]) n = max(n, i) m = max(m, j) A[i][j] = True if n < M: n += 1 if m < M: m += 1 WriteMatr(A, n, m)
</syntaxhighlight>