Sample 1
Input 1
4 4
..
.B
GGB.
P...
Output 1
17
DDDWAAWWDSASSDDWA
Sample 2
Input 2
4 5
.. G
.BBBG
..C..
P. .G
Output 2
21
WDDDWDSAAAAWWDSASDWDD
Sample 3
Input 3
5 5
.....
.BGB.
GC CG
.BGB.
P....
Output 3
32
DDWASAWSDDDDWADWWWAASDWDSWAAAASD
Sample 4
Input 4
5 6
..
GBG..
.CBB..
..GB..
P. G.
Output 4
24
WWWDDSASAWDDDSDDWAWADSAA
Sample 5
Input 5
5 4
..
.G.
GGB
.BB.
P...
Output 5
72
DWSDDWAAWAWWDSDSWAASDSSDDWASAAWWDWDSAASSDWSDDWAWWAWASDDSSSAAWDWSSDDWASAW
Code
#include<stdio.h>
#include<stdlib.h>
#define CharGround '.'
#define CharWall ' '
#define CharBox 'B'
#define CharGoal 'G'
#define CharBonG 'C'
#define CharPlay 'P'
typedef enum{False, True} Bool;
int n, m, s, b, pos2num[15][15];
char sce[15][15];
long long sta0, sta1;
struct
{
int x, y;
}num2pos[127];
struct NumLst
{
int numb[15], nump;
};
Bool charlegal(char c)
{
if(c == CharGround) return True;
if(c == CharWall) return True;
if(c == CharBox) return True;
if(c == CharGoal) return True;
if(c == CharBonG) return True;
if(c == CharPlay) return True;
return False;
}
#define dxw + 1
#define dxs - 1
#define dxa
#define dxd
#define dyw
#define dys
#define dya - 1
#define dyd + 1
#define dxx
#define dyx
#define near(num, dir) pos2num[num2pos[num].x dx##dir][num2pos[num].y dy##dir]
struct NumLst sta2slt(long long sta)
{
int i;
struct NumLst res;
res.nump = sta % s;
for(i = b - 1; i >= 0; i--)
sta /= s, res.numb[i] = sta % s;
return res;
}
long long slt2sta(struct NumLst slt)
{
int i;
long long res = 0;
for(i = 0; i < b; i++)
res = (res + slt.numb[i]) * s;
res += slt.nump;
return res;
}
void pushinit()
{
int i, j, sb, sg;
struct NumLst slt0, slt1;
s = sb = sg = 0;
for(i = 0; i <= n + 1; i++)
for(j = 0; j <= m + 1; j++)
pos2num[i][j] = -1;
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
{
if(sce[i][j] != CharWall)
num2pos[s].x = i, num2pos[s].y = j,
pos2num[i][j] = s++;
if(sce[i][j] == CharBox || sce[i][j] == CharBonG)
slt0.numb[sb++] = pos2num[i][j];
if(sce[i][j] == CharGoal || sce[i][j] == CharBonG)
slt1.numb[sg++] = pos2num[i][j];
if(sce[i][j] == CharPlay)
slt0.nump = slt1.nump = pos2num[i][j];
}
if(sb != sg)
{
printf("Box not equal Goal\n");
exit(0);
}
b = sb;
sta0 = slt2sta(slt0);
sta1 = slt2sta(slt1);
}
#define Chara 'A'
#define Chard 'D'
#define Chars 'S'
#define Charw 'W'
#define Charx 'X'
#define pushordw \
while(i + 1 < b && slt.numb[i + 1] < num2) \
slt.numb[i] = slt.numb[i + 1], i++;
#define pushords \
while(i > 0 && slt.numb[i - 1] > num2) \
slt.numb[i] = slt.numb[i - 1], i--;
#define pushorda
#define pushordd
#define pushordx
#define pushdir(sta, dir) \
({ \
int i, j, num1, num2; \
long long res; \
struct NumLst slt; \
slt = sta2slt(sta); \
if(Char##dir != 'X') \
num1 = near(slt.nump, dir); \
else \
num1 = sta0 % s; \
if(num1 != -1) \
{ \
for(i = 0; i < b; i++) \
if(slt.numb[i] == num1) \
break; \
if(i == b) \
{ \
slt.nump = num1; \
res = slt2sta(slt); \
} \
else if(Char##dir != 'X') \
{ \
num2 = near(num1, dir); \
if(num2 != -1) \
{ \
for(j = 0; j < b; j++) \
if(num2 == slt.numb[j]) \
break; \
if(j == b) \
{ \
pushord##dir \
slt.numb[i] = num2; \
slt.nump = num1; \
res = slt2sta(slt); \
} \
else \
res = -1; \
} \
else \
res = -1; \
} \
else \
res = -1; \
} \
else \
res = -1; \
res; \
})
#define LenQue 5000000
char opr[LenQue];
int dst[LenQue], pre[LenQue], hasidx[LenQue], haslst[LenQue];
long long que[LenQue];
int hasfun(long long x)
{
return x % 4999999;
}
void itq()
{
int i;
for(i = 0; i < LenQue; i++)
hasidx[i] = -1;
}
Bool inq(long long sta)
{
int i;
for(i = hasidx[hasfun(sta)]; i != -1; i = haslst[i])
if(que[i] == sta)
return True;
return False;
}
void enq(int rear)
{
int key;
key = hasfun(que[rear]);
haslst[rear] = hasidx[key];
hasidx[key] = rear;
}
#define pushque(dir) \
stan = pushdir(que[head], dir); \
if(stan != -1 && !inq(stan)) \
que[rear] = stan, \
dst[rear] = dst[head] + 1, \
pre[rear] = head, \
opr[rear] = Char##dir, \
enq(rear), \
rear++;
void output(int i)
{
if(i == 0)
return;
output(pre[i]);
printf("%c", opr[i]);
}
void push()
{
int head, rear;
long long stan;
pushinit();
head = rear = 0;
que[rear] = sta0, dst[rear] = 0, rear++;
itq(); enq(rear);
while(head < rear)
{
if(que[head] / s == sta1 / s)
break;
pushque(w)
pushque(s)
pushque(a)
pushque(d)
//pushque(x)
head++;
}
if(head == rear)
{
printf("No solution\n");
return;
}
printf("Solved Step %d\n", dst[head]);
output(head);
}
int main(int argc, char *argv[])
{
FILE *fp;
int i, j;
char tmp;
if(argc != 2)
{
printf("Parameter Error\n");
return 0;
}
if((fp = fopen(argv[1], "r")) == NULL)
{
printf("Input Error\n");
return 0;
}
fscanf(fp, "%d %d", &n, &m);
for(i = 0; i <= n + 1; i++)
for(j = 0; j <= m + 1; j++)
sce[i][j] = ' ';
tmp = fgetc(fp);
for(i = n; i >= 1; i--)
{
tmp = fgetc(fp);
for(j = 1; tmp != EOF && tmp != '\n'; j++)
{
if(!charlegal(tmp))
{
printf("Illegal Character\n");
return 0;
}
sce[i][j] = tmp;
tmp = fgetc(fp);
}
}
fclose(fp);
push();
return 0;
}
2023.3.6