Language: C++

#include <cstdio>
#include <queue>
#include <string>
#include <cctype>
#include <iostream>
using namespace std;

char f[16][16];
int fx,fy,N;
int dx[] = {0, 0, -1, 1, 0};
int dy[] = {0, -1, 0, 0, 1};

class Ghost
{
public:
	int x[3],y[3],c;
	bool r;
	
	Ghost(int* i, int* j, int c, bool r)
	:r(r),c(c)
	{
		for(int k=0; k<3; k++)
		{
			x[k]=i[k];
			y[k]=j[k];
			
		}
	}
};

bool move(int x, int y, int p)
{
	if(p>=N) return true;
	if(x<0||y<0||x>=fx||y>=fy) return false;
	if(f[x][y]=='#') return false;
	
	return true;
}

bool crash(int* x, int* y, int* gx, int* gy, int p)
{
	if(p<N) return false;
	for(int i=0; i<p; i++)
	for(int j=i+1; j<p; j++)
	{
		if(x[i]==x[j]&&y[i]==y[j]) return true;
		if(x[i]==gx[j]&&y[i]==gy[j]&&gx[i]==x[j]&&gy[i]==y[j]) return true;
	}
	return false;
}

short h[256][256][256][2];

int main()
{	
	while(scanf("%d%d%d",&fx,&fy,&N), (fx||fy||N))
	{
		int sx[3]={0},sy[3]={0},gx[3]={0},gy[3]={0};
		memset(h,0,sizeof(h));
			
		char s[20];
		
		getchar();
		for(int i=0; i<fy; i++)
		{
			gets(s);
			for(int j=0; j<fx; j++)
			{
				if(islower(s[j]))
				{
					sx[s[j]-'a']=j;
					sy[s[j]-'a']=i;
				}
				if(isupper(s[j]))
				{
					gx[s[j]-'A']=j;
					gy[s[j]-'A']=i;
				}
				
				f[j][i]=s[j];
			}
		}
		
		queue<Ghost> q;
		q.push(Ghost(sx,sy,1,0));
		q.push(Ghost(gx,gy,1,1));
		
		int th[3];
		for(int l=0; l<3; l++)
		{
			th[l]=(sx[l]<<4)+sy[l];
		}
		h[th[0]][th[1]][th[2]][0]=1;
		for(int l=0; l<3; l++)
		{
			th[l]=(gx[l]<<4)+gy[l];
		}
		h[th[0]][th[1]][th[2]][1]=1;
		
		while(!q.empty())
		{
			Ghost g=q.front(); q.pop();
			
			int th[3];

			for(int l=0; l<3; l++)
			{
				th[l]=(g.x[l]<<4)+g.y[l];
			}

			if(h[th[0]][th[1]][th[2]][!g.r])
			{
				printf("%d\n", g.c+h[th[0]][th[1]][th[2]][!g.r]-1);
				break;
			}
			
			
			int tx[3],ty[3];
			for(int i=0; i<3; i++)
			{
				tx[i]=g.x[i];
				ty[i]=g.y[i];
				
			}
			
			for(int i=0; i<5; i++)
			{
				tx[0]=g.x[0]+dx[i], ty[0]=g.y[0]+dy[i];
				if(!move(tx[0],ty[0],0))
				{
					tx[0]=g.x[0];
					ty[0]=g.y[0];
					continue;
				}
				
				for(int j=0; j<(N>1?5:1); j++)
				{
					tx[1]=g.x[1]+dx[j], ty[1]=g.y[1]+dy[j];
					if(N>=2)
					{
						if(!move(tx[1],ty[1], 1) || (crash(tx,ty,g.x,g.y,2)))
						{
							tx[1]=g.x[1];
							ty[1]=g.y[1];
							continue;
						}
					}
					
					for(int k=0; k<(N>2?5:1); k++)
					{
						tx[2]=g.x[2]+dx[k], ty[2]=g.y[2]+dy[k];
						if(N>=3)
						{
							if(!move(tx[2],ty[2], 2) || (crash(tx,ty,g.x,g.y,3)))
							{
								tx[2]=g.x[2];
								ty[2]=g.y[2];
								continue;
							}
						}
						for(int l=0; l<3; l++)
						{
							th[l]=(tx[l]<<4)+ty[l];
						}
	
						if(h[th[0]][th[1]][th[2]][g.r])
						{
							tx[2]=g.x[2];
							ty[2]=g.y[2];
							continue;
						}
						h[th[0]][th[1]][th[2]][g.r]=g.c;
					
						
						q.push(Ghost(tx, ty, g.c+1,g.r));
					}
				}
			}
		}
	}
}

Compiler output:
a.cc: In function 'int main()':
a.cc:59:17: error: 'memset' was not declared in this scope
   59 |                 memset(h,0,sizeof(h));
      |                 ^~~~~~
a.cc:6:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    5 | #include <iostream>
  +++ |+#include <cstring>
    6 | using namespace std;
a.cc:66:25: error: 'gets' was not declared in this scope; did you mean 'getw'?
   66 |                         gets(s);
      |                         ^~~~
      |                         getw