Se consideră o matrice cu N
linii și N
coloane care memorează doar cifre. Liniile și coloanele sunt numerotate de la 1
la N
. Se consideră de asemenea un vector v
de lungime 10
, în care v[i]
= costul cifrei i
(i = 0..9
). Trebuie să determinăm un drum de la coloana 1
la coloana N
, deci care pornește de la o componentă aflată pe coloana 1
la o componentă de pe coloana N
și fiecare pas se face dintr-o poziție (i,j)
într-una din pozițiile învecinate pe linie sau coloană, adică (i+1,j)
, (i-1,j)
, (i,j+1)
, (i,j-1)
, cu condiția să nu iasă din matrice. Costul unui astfel de drum este suma costurilor asociate componentelor prin care trece drumul.
Cerința
Să se determine numărul minim de cifre distincte prin care trece un drum de la coloana 1
la coloana N
. Dacă există mai multe astfel de drumuri, atunci se va determina costul minim al unui astfel de drum.
Date de intrare
Fișierul de intrare road.in
conține pe prima linie valoarea N
. Pe a doua linie se află exact 10
numere naturale v[0]
, v[1]
, …, v[9]
separate prin câte un spațiu. Pe următoarele N
linii se află câte N
cifre, fără spații între ele.
Date de ieșire
Fișierul de ieșire road.out
va conține pe prima linie un număr natural K
reprezentând numărul minim de cifre distincte prin care trece un drum de la coloana 1
la coloana N
. Pe linia a doua se află un singur număr natural reprezentând costul minim al unui drum care trece prin K
cifre distincte.
Restricții și precizări
2 ≤ N ≤ 100
1 ≤ v[i] ≤ 100
,i=0..9
Exemplu
road.in
6 8 1 2 1 9 14 8 8 6 9 287566 123444 983070 071311 548739 353665
road.out
3 9
Explicație
Drumul este marcat cu fundal gri în matricea de mai jos și folosește doar trei cifre distincte (1
, 2
și 3
), iar costul drumului este 9
.
De remarcat că mai există un drum care utilizează doar trei cifre distincte (format din toate elementele de pe ultima linie), dar are cost mai mare.
#include <bits/stdc++.h> using namespace std; ifstream fin("road.in"); ofstream fout("road.out"); struct pozitie{ int i,j; }; const int di[]={1,0,-1,0}; const int dj[]={0,1,0,-1}; int B[102][102],A[102][102],C[102][102],cc[11]; int n,dmin=10,cmin=1000000; int inside(int i, int j) { return i>=1 && j>=1 && i<=n && j<=n; } int verif(int x, int y) { return (x&(1<<y))!=0; } int nrdist(int x) { int c=0; while(x) { c=c+x%2; x=x/2; } return c; } queue<pozitie> Q; void LEE(int cod) { for(int i=1;i<=n;i++) { pozitie p; p.i=i; p.j=1; if(verif(cod,A[i][1])) { Q.push(p); B[i][1]=1; C[i][1]=cc[A[i][1]]; } } while(!Q.empty()) { int i=Q.front().i; int j=Q.front().j; for(int d=0;d<4;d++) { int ii=i+di[d]; int jj=j+dj[d]; if(inside(ii,jj) && verif(cod,A[ii][jj])) if(C[ii][jj]>C[i][j]+cc[A[ii][jj]]) { B[ii][jj]=B[i][j]+1; C[ii][jj]=C[i][j]+cc[A[ii][jj]]; pozitie pnou; pnou.i=ii; pnou.j=jj; Q.push(pnou); } } Q.pop(); } int costmin=100000; for(int i=1;i<=n;i++) if(B[i][n]>0 && C[i][n]<costmin) costmin=C[i][n]; if(costmin!=100000) { if(nrdist(cod)<dmin) { dmin=nrdist(cod); cmin=costmin; } else if(nrdist(cod)==dmin && cmin>costmin) cmin=costmin; } } int main() { fin>>n; for(int i=0;i<=9;i++) fin>>cc[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { char x; fin>>x; A[i][j]=x-'0'; } for(int k=0;k<=1023;k++) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { B[i][j]=0; C[i][j]=1000000; } LEE(k); } fout<<dmin<<'\n'<<cmin; return 0; }