UVA – 928 – Eternal Truths

  • Problem Statement : UVA – 928 – Eternal Truths
  • Difficulty :  Hard  – 236 DACU
  • Type : constrained BFS.
  • Description :
    • the main problem was to realize the differences between the normal BFS constrains and those of this problem
      • Here you are allowed to pass upon a certain cell many numbers of times with maximum of 3 times.
      • AND you may visit each cell only once ( which is the visit that will generate the shortest Path ) For each No of Jumps of the 1, 2 , 3 moves from the previous cell to the current one.
      • so if you are going to visit this cell with 2 Jumps, you are allowed to visit it if and only if it was not visisted before from a 2 Jumps move.
      • The fact that this soloution generates the shortest path is still inheriting it’s validity from the original BFS proof as we didn’t break the condition that we donot travel to a certain level of depth from the source , untill we finish the shorter level preceding it.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>

#define VALID(I, J, N, M) (I)>=0 && (J)>=0 && (I)<(N) && (J)<(M)
#define INF 1<<29
using namespace std;
typedef pair<int, int> Point;

int main() {
	int dx[]= {-1, 0, 0, 1};
	int dy[]= {0, -1, 1, 0};
	int T, N, M, i, j, sourceX, sourceY, endX, endY;
	int prevMoves = 0, curMoves=1, curX, curY, nextX, nextY;
	int delta, bad, JUMP;
	cin >> T;
	while (T--) {
		cin >> N >> M;
		char graph[N][M];
		int d[N][M][4];
		for (i = 0; i < N; i++)
			for (j = 0; j < M; j++) {
				cin >> graph[i][j];

				d[i][j][1]=d[i][j][2]=d[i][j][3] = INF;
				if(graph[i][j]=='S'){ sourceY=i; sourceX=j; }
				if(graph[i][j]=='E'){ endY=i; 	 endX=j;    }
			}

		queue< pair<Point, int> > que;
		d[sourceY][sourceX][0]= 0;
		que.push( pair<Point, int> (Point(sourceY, sourceX), 0));
		bool found = false;

		while(!que.empty() && !found){
			curY = que.front().first.first, curX=que.front().first.second;
			prevMoves = que.front().second, curMoves = prevMoves%3 +1;
			que.pop();

			for(delta=0; delta<4; delta++){
				nextY = curY + dy[delta]*curMoves, nextX =curX + dx[delta]*curMoves;
				if(VALID(nextY, nextX, N, M) && graph[nextY][nextX]!= '#' && d[nextY][nextX][curMoves]==INF){

					for(JUMP = 1, bad=false; JUMP<=curMoves; JUMP++)
						bad = bad || graph[curY + dy[delta]*JUMP][curX + dx[delta]*JUMP]=='#';
					if(bad)continue;

					d[nextY][nextX][curMoves]= d[curY][curX][prevMoves] +1;
					if(nextY==endY && nextX==endX) found=true;
					que.push( pair< Point, int> (Point(nextY, nextX), curMoves));
				}
			}
		}

		if(!found)
			cout << "NO" << endl;
		else
			cout << d[endY][endX][curMoves] << endl;

	}

	return 0;
}

2 thoughts on “UVA – 928 – Eternal Truths

  1. […] problem is very similar to UVA – 928 – Eternal Truths but with 2 dimensions of constrains. the two constrains […]

  2. Miguel Silva says:

    Thanks a lot for sharing your version! I have a question thought, why do you do use the variable INF (that has a fixed value, 536870912)?

Leave a comment