Considerăm un caroiaj dreptunghiular cu L
linii şi C
coloane. Liniile sunt numerotate de la 1
la L
de sus în jos şi coloanele de la 1
la C
, de la stânga la dreapta. Caroiajul este împărţit în L*C
pătrate cu latura egală cu două unităţi (2
). În fiecare pătrat al caroiajului se găseşte una dintre valorile 0
sau 1
. Se cunoaşte o poziţie (i, j)
a unuia dintre pătratele caroiajului (1 ≤ i ≤ L, 1 ≤ j ≤ C)
.
Trebuie construit un cerc care să îndeplinească următoarele proprietăţi:
- Centrul cercului să coincidă cu centrul pătratului din poziţia
(i, j)
; - Raza cercului să fie un număr natural nenul;
- Diferenţa dintre numărul de valori
1
şi numărul de valori0
aflate în pătratele acoperite de cerc să fie maximă.
Considerăm că un pătrat este acoperit de cerc dacă pătratul şi cercul au cel puţin un punct comun (aflat pe contur sau în interior). Dacă un pătrat este complet inclus în interiorul cercului se consideră că şi acel pătrat este acoperit de cerc (în figură, cercul desenat “acoperă” inclusiv pătratul din poziţia (3, 4)
). Cercul din figură are raza 3
.
Cerința
Determinaţi diferenţa maximă ce se poate obţine cu constrângerile de mai sus.
Date de intrare
Fişierul cerc1.in
conţine pe prima linie patru numere naturale L C i şi j
separate prin câte un spaţiu, cu semnificaţia din enunţ.
Pe următoarele L
linii se găsesc câte C
numere naturale din mulţimea {0, 1}
, care reprezintă valorile din pătratele caroiajului. Numerele de pe aceste linii nu sunt separate prin spaţii.
Date de ieșire
Fişierul cerc1.out
conţine pe prima linie un singur număr întreg reprezentând valoarea maximă a diferenţei cerute.
Restricții și precizări
1 ≤ L, C ≤ 1000
- Se recomandă citirea matricei din fişier linie cu linie şi nu element cu element;
- Cercul poate avea raza astfel încât să ocupe zone şi în afara caroiajului, dar acele zone nu influenţează valoarea căutată;
Exemplu
cerc1.in
5 5 3 4 00000 00101 01110 00110 10010
cerc1.out
4
Explicație
Valoarea maximă, 4
se poate obţine pentru un cerc de rază 3
.
Cum e corect?
cout < "As la info";
cout << "As la info";
cout >> "As la info";
Felicitări! Poți mai mult?
Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.
Greșit, dar nu-i bai!
Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.
Rezolvare
Iată rezolvarea de 100 de puncte pentru problema Cerc1:
//Marius Nicoli O(N^2)
#include <stdio.h>
#include <algorithm>
#include <vector>
#define DIM 1011
using namespace std;
struct pereche {
int d;
char v;
};
vector<int> F[8*DIM*DIM];
pereche B[DIM*DIM], P;
char A[DIM][DIM];
int L, C, X, Y, i, j, dx, dy, k, maxim, R, M, sum,pozMin, pozMax;
inline int modul(int X) {
return X > 0 ? X : -X;
}
int cmp(const pereche &a, const pereche &b) {
return a.d < b.d;
}
void sort(pereche *B, int k) {
pozMin = 2*DIM*DIM;
pozMax = 0;
for (int i = 1;i<=k; i++) {
P = B[i];
F[B[i].d].push_back(B[i].v);
if (P.d < pozMin)
pozMin = P.d;
if (P.d > pozMax)
pozMax = P.d;
}
vector<int>::iterator it;
k = 0;
for (i=pozMin;i<=pozMax;i++) {
for (it = F[i].begin();it!=F[i].end();it++) {
B[++k].v = *it;
B[k].d = i;
}
}
int q = 1;
}
int main() {
FILE *f = fopen("cerc1.in","r");
FILE *g = fopen("cerc1.out","w");
fscanf(f,"%d %d %d %d\n",&L, &C, &X, &Y);
for (i=1;i<=L;i++)
fscanf(f,"%s",A[i]+1);
fclose(f);
for (i=1;i<=L;i++)
for (j=1;j<=C;j++) {
P.v = A[i][j] - '0';
if (i == X && j == Y) {
P.d = 0;
B[++k] = P;
continue;
}
if (i == X) {
P.d = (modul (j - Y) << 1) - 1;
P.d *= P.d;
B[++k] = P;
continue;
}
if (j == Y) {
P.d = (modul (i - X) << 1)- 1;
P.d *= P.d;
B[++k] = P;
continue;
}
dx = (modul(i - X) << 1) - 1;
dy = (modul(j - Y) << 1) - 1;
P.d = dx * dx + dy * dy;
B[++k] = P;
}
sort(B, k);
R = 1;
M = 4 * ((L > C ? L : C) + 1);
M *= M;
i = 1;
maxim = -3000000;
B[k+1].d = 3000000;
while (R*R <= M) {
if (B[i].d <= R*R) {
sum += (B[i].v == 1 ? 1 : -1);
i++;
}
if (B[i].d > R*R) {
if (sum > maxim)
maxim = sum;
R++;
}
if (i > k)
break;
}
fprintf(g,"%d\n",maxim);
return 0;
}
Atenție
Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa .
Rezolvarea problemei #708 Cerc1
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #708 Cerc1 de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.
Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!