Cod sursa(job #1614038)

Utilizator Flavius08Flavius Aga Flavius08 Data 25 februarie 2016 19:32:47
Problema Rj Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.27 kb
#include <fstream>
#include <sstream>
#include <stdio.h>
#define nMax 100
#define mMax 100
#define DEBUG 0

#define DB if(DEBUG)
#define toupper1(c)   ((c>='a' && c<'z')?c-'a'+'A':c)
using namespace std;

int N,M,dcrt=0,vmax=nMax*mMax+1;
int X=vmax+'X',R=vmax+'R',J=vmax+'J',  Spatiu=vmax+' ';
int oras[nMax+1][mMax+1];
int iR, jR, iJ, jJ, iIntalnire=X, jIntalnire=X, tminDrum;
int di[]={1,0,-1,-1,-1,0,1,1};
int dj[]={-1,-1,-1,0,1,1,1,0};

typedef struct q {
    int *queue_i;
    int *queue_j;
    int F, R, qsize;
} Coada, *COADA;
/*
extern COADA initq(int SIZE_MAX);
extern void front(COADA q, int *first, int *second);
extern void remq(COADA q);
extern void addq(COADA q, int i, int j);
extern bool este_vida(COADA q);
extern bool este_plina(COADA q);
*/
COADA initq(int SIZE_MAX){
   COADA q = new Coada ;
   q->queue_i=new int[SIZE_MAX];
   q->queue_j=new int[SIZE_MAX];
   q->qsize= SIZE_MAX;
   q->F = q->R = 0;
   return q;
}
bool este_vida(COADA q){
    return q->queue_i==0 || q->F==q->R;
}
bool este_plina(COADA q){
    return q->queue_i!=0 && q->R >= q->qsize-1;
}

void front(COADA q, int *first, int *second){
    if(este_vida(q)) return;
    *first  = q->queue_i[q->F];
    *second = q->queue_j[q->F];
}

void addq(COADA q, int i, int j){
  if(este_plina(q)) {
        DB printf("\nadd - Coada plina(%d,%d)",q->F,q->R);
        return;
  }
  DB printf("\nadd(%d,%d)",i,j);
  q->queue_i[q->R]=i;
  q->queue_j[q->R]=j;
  q->R++;
}

void remq(COADA q){
  if(este_vida(q))
    return;
  DB printf("\nrem(%d,%d)\n",q->queue_i[q->F],q->queue_j[q->F]);
  q->F++; //rem
  if(este_plina(q)){ // deplasarea spre dreapta X X X 30 40 50 60 X  (q->F=3,q->R=7 => q->F=0,q->R=4)
    int i, k=0;
 DB printf("\nrem - Coada plina(%d,%d)",q->F,q->R);
    for(i=q->F; i<q->R; i++,k++){
        q->queue_i[k]=q->queue_i[i];
        q->queue_j[k]=q->queue_j[i];
    }
    q->F=0;
    q->R=k;
  }
}

void citiremat(char numefis[])
{
    int i,j,k=0, jcmin, lngLinie;
    char cc;
    string  linie;
    ifstream in(numefis);

    getline(in,linie);
    stringstream ssin(linie);
    ssin>>N>>M;
    DB printf("N=%d M=%d\n",N,M);

    for(i=1;i<=N;i++){
        for(j=1;j<=M;j++)
            oras[i][j]=Spatiu;

    getline(in,linie);
    lngLinie = linie.length();
    jcmin = (M<=lngLinie ? M : lngLinie);
    for(j=1;j<=jcmin;j++)
    {
        cc=linie[j-1];
        if(cc==0 || cc=='\r' || cc=='\n') break;
        if(cc==EOF) goto Final;

        DB k++;
        DB printf("%c",cc==' '?'.':cc);

        cc=toupper1(cc);
        if(cc=='X'||cc=='R'||cc=='J'||cc==' ')
                oras[i][j]=vmax+cc;
        if(cc=='R') {
                iR=i;
                jR=j;
        }
        else if(cc=='J') {
                iJ=i;
                jJ=j;
            }
        }
        DB printf("  --jcmin=%d\n", jcmin);
        linie="";
    }
     Final: DB printf(" iR=%d jR=%d iJ=%d jJ=%d k=%d ********\n", iR, jR, iJ, jJ, k);
}
void afismat(char * numefis)
{
    ofstream out(numefis);
    int i,j;
    DB printf("\n");
    for(i=1;i<=N;i++)
    {
        out<<endl;
        DB printf("\n");
        for(j=1;j<=M;j++) {
           out<<oras[i][j]<<" ";
           DB {
               if(oras[i][j]>vmax)
                    printf(" %c ",oras[i][j]-vmax);
               else printf("%2d ",oras[i][j]);
           }
        }
    }
}

void drecurs(int i, int j, int d){
    int dcrt=d;
    int k, iv, jv, oc ;
    for(k=0;k<8;k++){
        iv=i+di[k];
        if(iv<1||iv>N) continue;
        jv=j+dj[k];
        if(jv<1||jv>M) continue;
        oc=oras[iv][jv];
        if(oc==X || oc==R || oc==J) continue;
        if(oc > dcrt) {
                oras[iv][jv]= dcrt;
                drecurs(iv,jv, dcrt+1);
        }
    }
}

int timpminim(int i, int j){
    int k, iv, jv, oc,tmin=X ;
    for(k=0;k<8;k++){
        iv=i+di[k];
        if(iv<1||iv>N) continue;
        jv=j+dj[k];
        if(jv<1||jv>M) continue;
        oc=oras[iv][jv];
        if(oc==X || oc==R || oc==J) continue;
        if(oc%2==0) continue;
        if(oc < tmin) {
                tmin=oc;
        }
    }
    return tmin;
}

void cautaPunctDeIntalnire(int i, int j, int tstart,int tstop){
    int k, iv, jv, oc;
    DB printf("\ni=%d j=%d tstart=%d tstop=%d", i,j,tstart, tstop);
    for(k=0;k<8;k++){
        iv=i+di[k];
        if(iv<1||iv>N) continue;
        jv=j+dj[k];
        if(jv<1||jv>M) continue;
        oc=oras[iv][jv];
        if(oc<0) continue;
        if(oc==X || oc==R || oc==J) continue;
        if(oc == tstop) {
            if(iv<iIntalnire) {
                iIntalnire=iv;
                jIntalnire=jv;
            }
            if (iv==iIntalnire && jv<jIntalnire) {
                        jIntalnire=jv;
            }
            continue;
        }
        if(oc==tstart) {
            oras[iv][jv] = -oras[iv][jv];
            cautaPunctDeIntalnire(iv,jv, tstart-1,tstop);
        }
    }
}
int find_shortest_path();
int main()
{   int tmin;
    citiremat("rj.in");
    DB afismat("rjinit1.out");

    //drecurs(iR, jR, 1);
    tminDrum=find_shortest_path();
    DB printf("T_shortest_path=%d", tminDrum);
    DB afismat("rj1.out");
    tminDrum = timpminim(iJ,jJ);
    tmin=(tminDrum+1)/2;
    DB printf("\ntmin=%d",tminDrum);

    cautaPunctDeIntalnire(iJ,jJ,tminDrum,tmin);
    DB printf(" Intalnire=(%d, %d)",iIntalnire,jIntalnire);

    ofstream out("rj.out");
    out<< tmin+1 << " " <<iIntalnire<<" " <<jIntalnire;
    DB printf("\n%d %d %d",tmin+1,iIntalnire,jIntalnire);
    return 0;
}
int find_shortest_path()
{
    int pfirst,psecond;
    int k, iv, jv, oc ;
    COADA q=initq(nMax);

    addq(q,iR,jR);
    oras[iR][jR]=0;
  while (! este_vida(q)) { // coada nu este vida
    front(q, &pfirst, &psecond);
    remq(q);

    if (pfirst == iJ && psecond == jJ)
      break;

    for(k=0;k<8;k++){
        iv=pfirst+di[k];
        if(iv<1||iv>N) continue;
        jv=psecond+dj[k];
        if(jv<1||jv>M) continue;
        oc=oras[iv][jv];
        if(oc==X || oc==R ) continue;
        if(oc >= vmax) { //nevizitat
            addq(q, iv, jv);
            oras[iv][jv]= oras[pfirst][psecond] + 1;;
        }
    }
  }
   return oras[iJ][jJ];
}