Atunci când este plictisit, Costel inventează jocuri logice şi încearcă să le rezolve. Într-o zi Costel ia o tablă dreptunghiulară împărţită în M*N
pătrăţele identice, asemănătoare unei table de şah, şi aşează pe aceasta cuburi identice astfel încât, pe fiecare pătrat al tablei să se afle cel puţin un cub şi cel mult 10
cuburi suprapuse. Costel determină numărul minim de cuburi aşezate pe o poziţie a tablei, notat cu MIN
.
El defineşte noţiunea de mutare astfel: alege patru pătrăţele învecinate, care formează un pătrat compus din 2*2
pătrăţele şi ridică toate cuburile de pe aceste poziţii astfel ca, pe fiecare dintre cele patru pătrăţele, să existe un număr de cuburi egal cu MIN
. Efortul necesar efectuării mutării este egal cu MAX-MIN
, unde MAX
reprezintă numărul maxim de cuburi aflat pe unul dintre cele patru pătrăţele alese.
Scopul jocului este acela de a obţine acelaşi număr de cuburi, egal cu valoarea MIN
, pe fiecare pătrăţel de pe tablă, efectuând un şir de mutări ce necesită un efort total minim. Efortul total depus pentru rezolvarea jocului este egal suma eforturilor mutărilor efectuate.
Cerința
Determinaţi valoarea efortului total minim depus pentru rezolvarea jocului.
Date de intrare
Fişierul de intrare joc1.in
are următoarea structură:
- pe prima linie se află două numere naturale
M
şiN
, separate printr-un singur spaţiu, reprezentând numărul liniilor, respectiv numărul coloanelor tablei de joc. - pe următoarele
M
linii se află câteN
numere naturale, separate prin câte un spaţiu, reprezentând numărul iniţial de cuburi aflate pe fiecare pătrăţel al tablei de joc.
Date de ieșire
Fișierul de ieșire joc1.out
va conține un singur număr natural reprezentând valoarea efortului total minim.
Restricții și precizări
M
şiN
sunt numere naturale mai mari sau egale cu2
cu proprietatea că4 ≤ M x N ≤ 18
- Numărul cuburilor plasate pe o poziţie a tablei este un număr natural între
1
şi10
.
Exemplu
joc1.in
3 4 2 3 2 2 2 4 3 2 3 2 4 2
joc1.out
4
Explicație
Minimul este 2
. O succesiune optimă de mutări poate fi:
- Mutarea 1: Se aleg poziţiile
(2,2)
,(2,3)
,(3,2)
şi(3,3)
. Efortul este4 – 2 = 2
- Mutarea 2: Se aleg poziţiile
(1,1)
,(1,2)
,(2,1)
şi(2,2)
. Efortul este3 – 2 = 1
- Mutarea 3: Se aleg poziţiile
(2,1)
,(2,2)
,(3,1)
şi(3,2)
. Efortul este3 – 2 = 1
Efortul total este 4
.
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 Joc1:
/* solutia 1 - 100p*/
#include <iostream>
#include <fstream>
#define IN "joc1.in"
#define OUT "joc1.out"
#define Nmax 10
#define NivMax 11
#define MaxQ 100001
using namespace std;
typedef short int Mat[10][10];
Mat T, C[MaxQ];
int E[MaxQ], p, u;
int M,N, NrBuf;
int NivMin, n, gata;
int maxim(int a, int b)
{
return a<b ? b : a;
}
void copy(Mat T, Mat D)
{
int i,j;
for(i=1;i<=M;i++)
for(j=1;j<=N;j++) T[i][j] = D[i][j];
}
int final(int p)
{
//verific daca am o configuratie finala
int i,j;
for(i=1;i<=M;i++)
for(j=1;j<=N;j++)
if(C[p][i][j] != NivMin) return 0;
return 1;
}
int exista(int u)
{
//verific daca a o configuratie a mai aparut
int i,j,k,ok;
for(k=u-1;k>1;k--)
{
ok=1;
for(i=1;i<=M;i++)
for(j=1;j<=N;j++)
if(C[u][i][j] != C[k][i][j]) ok=0;
if(ok && E[k]<=E[u]) return 1;
}
return 0;
}
int main()
{
int i,j, Pi, Pj;
ifstream F(IN);
ofstream G(OUT);
//citesc datele de intrare, calculand nivelul minim
NivMin = NivMax;
F>>M>>N;
for(i=1;i<=M;i++)
for(j=1;j<=N;j++)
{
F>>T[i][j];
if(T[i][j]<NivMin) NivMin = T[i][j];
}
F.close();
//incep jocul
n = (M-1)*(N-1);
gata = 0;
NrBuf = 1000000;
//coada contine configuratia initiala
p=u=1;
copy(C[u],T);
E[u] = 0;
//expandez coada
while(p<=u)
{
if(final(p)) {if(E[p]<NrBuf) NrBuf = E[p];}
else
for(i=1; i<=n; i++)
{
u++;
Pi = i/(N-1)+1;
if(i%(N-1) == 0) Pi=Pi-1;
Pj = (i%(N-1) == 0 ? N-1 : i%(N-1));
E[u] = E[p] + maxim(maxim(C[p][Pi][Pj]- NivMin,C[p][Pi][Pj+1]- NivMin), maxim(C[p][Pi+1][Pj]- NivMin, C[p][Pi+1][Pj+1]- NivMin));
copy(C[u],C[p]);
C[u][Pi][Pj] = C[u][Pi][Pj+1] = C[u][Pi+1][Pj] = C[u][Pi+1][Pj+1] = NivMin;
if(final(u)) {if(E[u]<NrBuf) NrBuf = E[u];}
if(exista(u)) u--;
}
p++;
}
G<<NrBuf<<'\n';
G.close();
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 #727 Joc1
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #727 Joc1 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!