Rezolvare completă PbInfo #1108 Traseu

Într-un oraș există un hotel de formă cubică, cu N etaje, numerotate de la 1 la N. Suprafața fiecărui etaj K (1 ≤ K ≤ N) este pătratică și este împărțită în N x N camere identice alăturate, dispuse pe N linii și N coloane, fiecare cameră având drept etichetă un triplet de numere naturale (K L C) (K=etajul, L=linia, C=coloana, 1 ≤ L, C ≤ N), ca în imaginea alăturată.

Dintre cele N x N x N camere ale hotelului, una este specială deoarece în ea locuiește de mult timp un șoricel. Fiind isteț, el știe eticheta camerei în care se află precum și eticheta camerei în care bucătarul hotelului depozitează alimente.

Studiind hotelul, șoricelul a constatat că pe fiecare etaj, din orice cameră poate intra în toate camerele care au un perete comun cu aceasta (existând un mic orificiu pentru aerisire).

De asemenea, șoricelul a constatat că din fiecare cameră (situată la etajele 2, 3, …, sau N-1) poate intra în camera situată imediat deasupra ei și în camera situată imediat sub ea.

Fiind un șoricel binecrescut, el nu intră în nicio cameră ocupată de clienți ca să nu-i deranjeze. Hotelul având mulți clienți, șoricelul trebuie să-și găsească cel mai scurt traseu de la camera lui la camera cu alimente, traseu care să treacă printr-un număr minim de camere, toate neocupate.

Cerinţe:

Se cere să se determine:
a) numărul de camere prin care trece cel mai scurt traseu al șoricelului de la camera lui la camera cu alimente (inclusiv camera lui şi camera cu alimente);
b) etichetele camerelor prin care trece traseul determinat la punctul a).

Date de intrare

Fișierul de intrare traseu.in conține:

  • pe prima linie, două numere naturale N și M separate printr-un spațiu, N cu semnificația din enunț iar M reprezentând numărul de camere ocupate de clienţii hotelului;
    pe a doua linie, trei numere naturale K1 L1 C1, separate prin câte un spațiu, reprezentând eticheta camerei în care se află șoricelul;
  • pe a treia linie, trei numere naturale K2 L2 C2, separate prin câte un spațiu, reprezentând eticheta camerei în care sunt depozitate alimentele;
  • pe fiecare dintre următoarele M linii, câte trei numere naturale X Y Z, separate prin câte un spaţiu, reprezentând etichetele celor M camere ocupate de clienți.

Date de ieșire

Fișierul de ieșire traseu.out va conține pe prima linie un număr natural T reprezentând numărul de camere prin care trece cel mai scurt traseu al șoricelului de la camera lui la camera cu alimente determinat la punctul a). Pe fiecare din următoarele T linii, se vor scrie câte trei numere naturale X Y Z, separate prin câte un spaţiu, reprezentând etichetele camerelor prin care trece traseul determinat la punctul a), în ordinea în care sunt parcurse camerele de către șoricel pentru a ajunge din camera lui în camera cu alimente.

Restricții și precizări

  • 2 ≤ N ≤ 100; 1 ≤ M ≤ 5000 și M < N*N-2
  • Șoricelul nu intră decât în camere neocupate de clienți.
  • Camera șoricelului este o cameră neocupată de clienți.
  • Dacă există mai multe trasee ale șoricelului de la camera lui la camera de alimente care trec prin exact T camere, atunci traseul afișat va fi cel mai mic traseu din punct de vedere lexicografic.
  • Eticheta (X1 Y1 Z1) se consideră strict mai mică în sens lexicografic ca eticheta (X2 Y2 Z2) dacă este satisfăcută doar una dintre condițiile:
    1. X1 < X2
    2. X1 = X2 și Y1 < Y2
    3. X1 = X2 și Y1 = Y2 și Z1 < Z2
  • Eticheta X1 Y1 Z1 se consideră egală cu eticheta X2 Y2 Z2 dacă X1 = X2 și Y1 = Y2 și Z1 = Z2. Vom scrie egalitatea lor astfel: (X1 Y1 Z1) = (X2 Y2 Z2).
  • Traseul ce trece (în această ordine) prin camerele cu etichetele (X1 Y1 Z1), (X2 Y2 Z2),…, (XT YT ZT) este mai mic din punct de vedere lexicografic ca traseul (A1 B1 C1), (A2 B2 C2),…, (AT BT CT) dacă există un indice J (1≤J≤T) astfel încât (X1 Y1 Z1) = (A1 B1 C1), (X2 Y2 Z2) = (A2 B2 C2)…., (XJ-1 YJ-1 ZJ-1) = (AJ-1 BJ-1 CJ-1) iar eticheta (XJ YJ ZJ) este strict mai mică ca eticheta (AJ BJ CJ).
  • Se acordă: 40% din punctaj pentru determinarea corectă a numărului T și 100% din punctaj pentru rezolvarea corectă a ambelor cerințe.
  • Se garantează că există soluție pentru ambele cerințe, pentru toate datele de test.

Exemplu

traseu.in

3 4
1 1 1
3 3 3
3 3 1
2 1 1
3 1 1
3 1 3

traseu.out

7
1 1 1
1 1 2
1 1 3
1 2 3
1 3 3
2 3 3
3 3 3

Explicație

Hotelul are trei etaje (1, 2 şi 3). Pe fiecare etaj sunt 3*3 camere. Șoricelul se află în camera cu eticheta (1 1 1) iar camera cu alimente are eticheta (3 3 3).

Sunt 4 camere ocupate de clienţi. Acestea au etichetele : 3 3 1, 2 1 1, 3 1 1, 3 1 3.
Traseul cel mai scurt trece prin T=7 camere. Sunt mai multe astfel de trasee. De exemplu:

  1. (1 1 1, 1 1 2, 1 1 3, 1 2 3, 1 3 3, 2 3 3, 3 3 3)
  2. (1 1 1, 1 1 2, 1 1 3, 2 1 3, 2 2 3, 3 2 3, 3 3 3)
  3. (1 1 1, 1 2 1, 1 3 1, 1 3 2, 2 3 2, 3 2 3, 3 3 3)
  4. etc.

Cel mai mic astfel de traseu (în sens lexicografic) este traseul 1).

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 Traseu:

#include <fstream>
#include <iostream>

using namespace std;

int a[105][105][105], p, u,i;
short int n,m,k1,l1,c1,k2,l2,c2,x,y,z,xc,yc,zc;
struct camera{short int x,y,z;}c[1000005];
short int dx[]={-1,0,0,0,0,1}, dy[]={0,-1,0,0,1,0},dz[]={0,0,-1,1,0,0};
ofstream g("traseu.out");

void citeste()
{ifstream f("traseu.in");
 f>>n>>m;
 f>>k1>>l1>>c1>>k2>>l2>>c2;
 for(i=1;i<=m;i++)
   {
    f>>x>>y>>z;
    a[x][y][z]=-1;
   }

 }
void bordare()
{ for(int i=0;i<=n+1;i++)
  for(int j=0;j<=n+1;j++)
  {a[0][i][j]=-1;a[n+1][i][j]=-1;
   a[i][0][j]=-1;a[i][n+1][j]=-1;
   a[i][j][0]=-1;a[i][j][n+1]=-1;
  }
}
 void coada()
 { p=u=1;
   c[1].x=k1; c[1].y=l1; c[1].z=c1;
   a[k1][l1][c1]=1;
   while((p<=u)&& (a[k2][l2][c2]==0))
   { x=c[p].x; y=c[p].y;z=c[p++].z;
     for(i=0;i<6;i++)
     { xc=x+dx[i]; yc=y+dy[i]; zc=z+dz[i];
       if (a[xc][yc][zc]==0)
         { u++;a[xc][yc][zc]=a[x][y][z]+1;c[u].x=xc; c[u].y=yc; c[u].z=zc;}
     }

    }
 }
void drum(int val)

 { while(val>0)
   {   if (a[x-1][y][z]==val-1) --x;
     else
       if (a[x][y-1][z]==val-1) --y;
       else
        if (a[x][y][z-1]==val-1) --z;
        else
        if (a[x][y][z+1]==val-1) ++z;
        else
        if (a[x][y+1][z]==val-1) ++y;
        else
        if (a[x+1][y][z]==val-1) ++x;
     --val;
     c[val].x=x; c[val].y=y; c[val].z=z;

   }
}
 int main()
 { citeste();bordare();
   coada();
   int val=a[k2][l2][c2];
   g<<val<<endl;
   c[val].x=k2; c[val].y=l2; c[val].z=c2;
   drum(val);
   for(int i=1;i<=val; i++)
        g<<c[i].x<<<<c[i].y<<<<c[i].z<<endl;
   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 Adresa de email.

Rezolvarea problemei #1108 Traseu

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1108 Traseu 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!