We are given a map of sides of length n and m (both n and m are less than 1000), divided into n*m fields (squares of side 1). The map looks (for example) like this:
. z x . x
. x x . .
. . x . x
x . . n .
Here n=4 and m=5. We start from the field with "z" and we have to get to the field with "n". Suppose we are at position (x, y). Then, we can only move to fields with coordinates: (x+1, y+2), (x+1, y-2), (x-1, y+2), (x-1, y-2), (x+2, y+1), (x+2, y-1), (x-2, y+1), (x-2, y-1).
The next restriction is that we can only move to fields with "." (or "n") - we must avoid fields with "x". We have to compute the smallest number of moves required to get from the field with "z" to the field with "n" (if it's impossible, we have to output "NO"). The correct answer for the given sample map is 3. My program works as follows: we input the map, then we represent it as graph - and then we run the breadth-first search. As far as I've tested, my program outputs correct values.
My biggest concern is that I use too much memory. Also, I wonder if there's a better method for solving such problems.
Here's the code:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int n, m, start, finish;
vector <int> graph[990000];
bool visited[990000];
int mydistance[990000];
queue <int> myqueue;
void BFS(int s){
mydistance[s]=0;
myqueue.push(s);
while (!myqueue.empty()){
if (visited[finish]){
return;
}
int u=myqueue.front();
myqueue.pop();
for (int i=0; i<graph[u].size(); i++){
if (!visited[graph[u][i]]){
mydistance[graph[u][i]]=mydistance[u]+1;
myqueue.push(graph[u][i]);
}
}
visited[u]=true;
}
}
int main(){
cin >> n >> m;
char map[n][m];
for (int i=0; i<n; i++){
for (int j=0; j<m; j++){
char x;
cin >> x;
map[i][j]=x;
}
}
for (int i=0; i<n; i++){
for (int j=0; j<m; j++){
int a=i*m+j;
if (map[i][j]=='z'){ start=a; }
if (map[i][j]=='n'){ finish=a; }
if ((j<m-1) && (i<n-2)) { if (map[i+2][j+1]!='x'){ graph[a].push_back(a+2*m+1); }} // x+1 y+2
if ((j<m-1) && (i>1)) { if (map[i-2][j+1]!='x'){ graph[a].push_back(a-2*m+1); }} // x+1 y-2
if ((j>0) && (i<n-2)) { if (map[i+2][j-1]!='x'){ graph[a].push_back(a+2*m-1); }} // x-1 y+2
if ((j>0) && (i>1)) { if (map[i-2][j-1]!='x'){ graph[a].push_back(a-2*m-1); }} // x-1 y-2
if ((j<m-2) && (i<n-1)) { if (map[i+1][j+2]!='x'){ graph[a].push_back(a+m+2); }} // x+2 y+1
if ((j<m-2) && (i>0)) { if (map[i-1][j+2]!='x'){ graph[a].push_back(a-m+2); }} // x+2 y-1
if ((j>1) && (i<n-1)) { if (map[i+1][j-2]!='x'){ graph[a].push_back(a+m-2); }} // x-2 y+1
if ((j>1) && (i>0)) { if (map[i-1][j-2]!='x'){ graph[a].push_back(a-m-2); }} // x-2 y-1
mydistance[a]=-1;
}
}
BFS(start);
if (mydistance[finish]==-1) {
cout << "NO";
} else {
cout << mydistance[finish];
}
return 0;
}