Language: C++

#include <cstdio>
#include <cstring>
#include <iostream>
#include <utility>
#include <queue>
#include <string>
#define INF 1e7
using namespace std;
typedef pair<int,int> P;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int ddx[4][2]={
	2,2,
	0,1,
	-1,-1,
	0,1
};
int ddy[4][2]={
	0,1,
	2,2,
	0,1,
	-1,-1
};
P add(P p1,P p2){
	P p3;
	p3.x=
	return P(p1.first+p2.first,p1.second+p2.second);
}
P minus(P p1,P p2){
	return P(p1.first-p2.first,p1.second-p2.second);
}

int h,w;
int fie[51][51];
struct data{
	int cost,pdir;
	P k;
	data(){}
	data(P kk,int cc,int pp){
		k=kk;
		cost=cc;
		pdir=pp;
	}
	bool operator<(const data &d1)const{
		if(cost!=d1.cost)return cost>d1.cost;
		if(k!=d1.k)return k>d1.k;
		return pdir>d1.pdir;
	}
};

struct data2{
	P k,o[2];
	data2(){}
	data2(P kk,P o1,P o2){
		k=kk;
		o[0]=o1;
		o[1]=o2;
	}
};

bool cross(P a,P b){
	if(a==b)return true;
	if(a==(b+P(1,0)))return true;
	if(a==(b+P(0,1)))return true;
	if(a==(b+P(1,1)))return true;
	return false;
}

bool canmove(P a){
	if(a.first>=0 && a.first<w && a.second>=0 && a.second<h)return true;
	return false;
}

bool same(P a,P b){
	return a.first==b.first && a.second==b.second;
}

bool same(data2 a,data2 b){
	if(!same(a.k,b.k))return false;
	if(!same(a.o[0],b.o[0]))return false;
	if(!same(a.o[1],b.o[1]))return false;
	return true;
}

int distp[51][51];
int move_pawn(P f,P t){
	for(int i=0;i<50;i++){
		for(int j=0;j<50;j++){
			distp[i][j]=INF;
		}
	}
	queue<P> que;
	que.push(f);
	distp[f.first][f.second]=0;
	while(que.size()){
		P q=que.front();
		que.pop();
		if(q==t)return distp[q.first][q.second];
		for(int i=0;i<4;i++){
			P nq=q+P(dy[i],dx[i]);
			if(nq.first>=0 && nq.first<h && nq.second>=0 && nq.second<w){
				if(distp[nq.first][nq.second]==INF && fie[nq.first][nq.second]!=-1){
					distp[nq.first][nq.second]=distp[q.first][q.second]+1;
					que.push(P(nq));
				}
			}
		}
	}
	return INF;
}

data first_moveking(P k,P o1,P o2,int dir){
	data res;
	fie[k.first][k.second]=-1;
	fie[k.first+1][k.second]=-1;
	fie[k.first][k.second+1]=-1;
	fie[k.first+1][k.second+1]=-1;
	int cost1=move_pawn(o1,k+P(ddy[dir][0],ddx[dir][0]))+move_pawn(o2,k+P(ddy[dir][1],ddx[dir][1]));
	int cost2=move_pawn(o1,k+P(ddy[dir][1],ddx[dir][1]))+move_pawn(o2,k+P(ddy[dir][0],ddx[dir][0]));
	res.cost=min(cost1,cost2)+1;
	fie[k.first][k.second]=0;
	fie[k.first+1][k.second]=0;
	fie[k.first][k.second+1]=0;
	fie[k.first+1][k.second+1]=0;
	res.pdir=dir;
	res.k=k+P(dy[dir],dx[dir]);
	return res;
}

data moveking(data q,int dir){
	data res;
	P k=q.k;
	fie[k.first][k.second]=-1;
	fie[k.first+1][k.second]=-1;
	fie[k.first][k.second+1]=-1;
	fie[k.first+1][k.second+1]=-1;
	P o1=k+P(ddy[(q.pdir+2)%4][0],ddx[(q.pdir+2)%4][0]);
	P o2=k+P(ddy[(q.pdir+2)%4][1],ddx[(q.pdir+2)%4][1]);
	int cost1=move_pawn(o1,k+P(ddy[dir][0],ddx[dir][0]))+move_pawn(o2,k+P(ddy[dir][1],ddx[dir][1]));
	int cost2=move_pawn(o1,k+P(ddy[dir][1],ddx[dir][1]))+move_pawn(o2,k+P(ddy[dir][0],ddx[dir][0]));
	res.cost=min(cost1,cost2)+1+q.cost;
	fie[k.first][k.second]=0;
	fie[k.first+1][k.second]=0;
	fie[k.first][k.second+1]=0;
	fie[k.first+1][k.second+1]=0;
	res.pdir=dir;
	res.k=k+P(dy[dir],dx[dir]);
	return res;
}

int dist[51][51][4];
int dijkstra(P s,P o1,P o2){
	int i,j,k;
	priority_queue<data> que;
	for(i=0;i<50;i++){
		for(j=0;j<50;j++){
			for(k=0;k<4;k++){
				dist[i][j][k]=INF;
			}
		}
	}
	for(i=0;i<4;i++){
		if(s.second+dx[i]>=0 && s.second+dx[i]<w-1 && s.first+dy[i]>=0 && s.first+dy[i]<h-1){
			data si=first_moveking(s,o1,o2,i);
			if(si.cost<INF){
				que.push(si);
				dist[si.k.first][si.k.second][si.pdir]=si.cost;
			}
		}
	}
	while(que.size()){
		data q=que.top();
		que.pop();
		if(q.cost>dist[q.k.first][q.k.second][q.pdir])continue;
		if(q.k.first+q.k.second==0)return q.cost;
		for(int i=0;i<4;i++){
			if(q.k.second+dx[i]>=0 && q.k.second+dx[i]<w-1 && q.k.first+dy[i]>=0 && q.k.first+dy[i]<h-1){
				data nq=moveking(q,i);
				if(nq.cost<dist[nq.k.first][nq.k.second][nq.pdir]){
					dist[nq.k.first][nq.k.second][nq.pdir]=nq.cost;
					que.push(nq);
				}
			}
		}
	}
	return -1;
}

int main(void){
	while(1){
		scanf("%d %d",&h,&w);
		if(h+w==0)break;
		P k,o[2];
		k.first=k.second=-1;
		int cnt=0;
		memset(fie,0,sizeof(fie));
		for(int i=0;i<h;i++){
			string str;
			cin >> str;
			for(int j=0;j<w;j++){
				if(str[j]=='*')fie[i][j]=-1;
				if(str[j]=='X'){
					if(k.first==-1){
						k.second=j;
						k.first=i;
					}
				}
				if(str[j]=='.'){
					o[cnt].second=j;
					o[cnt++].first=i;
				}
			}
		}
		if(k.first+k.second==0)printf("0\n");
		else if(cnt<2)printf("-1\n");
		else printf("%d\n",dijkstra(k,o[0],o[1]));
	}
	return 0;
}

Compiler output:
a.cc: In function 'P add(P, P)':
a.cc:26:12: error: 'P' {aka 'struct std::pair<int, int>'} has no member named 'x'
   26 |         p3.x=
      |            ^
a.cc:27:9: error: expected primary-expression before 'return'
   27 |         return P(p1.first+p2.first,p1.second+p2.second);
      |         ^~~~~~
a.cc:28:1: warning: no return statement in function returning non-void [-Wreturn-type]
   28 | }
      | ^
a.cc: In function 'bool cross(P, P)':
a.cc:63:17: error: no match for 'operator+' (operand types are 'P' {aka 'std::pair<int, int>'} and 'P' {aka 'std::pair<int, int>'})
   63 |         if(a==(b+P(1,0)))return true;
      |                ~^~~~~~~
      |                | |
      |                | pair<[...],[...]>
      |                pair<[...],[...]>
In file included from /usr/include/c++/14/string:48,
                 from /usr/include/c++/14/bits/locale_classes.h:40,
                 from /usr/include/c++/14/bits/ios_base.h:41,
                 from /usr/include/c++/14/ios:44,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:3:
/usr/include/c++/14/bits/stl_iterator.h:627:5: note: candidate: 'template<class _Iterator> constexpr std::reverse_iterator<_Iterator> std::operator+(typename reverse_iterator<_Iterator>::difference_type, const reverse_iterator<_Iterator>&)'
  627 |     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:627:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::reverse_iterator<_Iterator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/stl_iterator.h:1798:5: note: candidate: 'template<class _Iterator> constexpr std::move_iterator<_IteratorL> std::operator+(typename move_iterator<_IteratorL>::difference_type, const move_iterator<_IteratorL>&)'
 1798 |     operator+(typename move_iterator<_Iterator>::difference_type __n,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1798:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::move_iterator<_IteratorL>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
In file included from /usr/include/c++/14/string:54:
/usr/include/c++/14/bits/basic_string.h:3598:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3598 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3598:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3616:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3616 |     operator+(const _CharT* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3616:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   mismatched types 'const _CharT*' and 'std::pair<int, int>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3635:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3635 |     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3635:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3652:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)'
 3652 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3652:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3670:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, _CharT)'
 3670 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3670:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3682:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3682 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3682:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3689:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3689 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3689:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3696:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3696 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3696:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3719:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3719 |     operator+(const _CharT* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3719:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   mismatched types 'const _CharT*' and 'std::pair<int, int>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3726:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3726 |     operator+(_CharT __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3726:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3733:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const _CharT*)'
 3733 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3733:5: note:   template argument deduction/substitution failed:
a.cc:63:23: note:   'P' {aka 'std::pair<int, int>'} is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   63 |         if(a==(b+P(1,0)))return true;
      |                       ^
/usr/include/c++/14/bits/basic_string.h:3740:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, _CharT)'
 3740 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3740:5: note:   template argument deductio