描述:这道题更让人头疼,想破头才知道移动的顺序必须按照字母的顺序,就是得按照D、L、R、U这个顺寻才能过,哪有这么坑人的啊,无语了……
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define NX 1000003
int N,M,flag;
char d[]= {'D','L','R','U'};
int next[NX],head[NX];
char str[NX][14][22],s[1000];
int count[NX][3];
int move[4][2]= {{0,-1},{0,1},{1,0},{-1,0}};
void search(int c,int x,int y,int rear)
{
if(str[rear][x][y]==c) str[rear][x][y]=' ';
else return;
search(c,x+1,y,rear);
search(c,x,y+1,rear);
search(c,x-1,y,rear);
search(c,x,y-1,rear);
}
int hash(int rear)
{
int c=0;
for(int i=0; i<N; i++)
for(int j=0; j<M; j++)
if(str[rear][i][j]>='1'&&str[rear][i][j]<='3') c=(c*5+str[rear][i][j]-'0')%NX;
else if(str[rear][i][j]==' ') c=(c*5)%NX;
else if(str[rear][i][j]=='@') c=(c*5+4)%NX;
return c;
}
bool insert(int c,int rear)
{
int x=head[c];
while(x!=-1)
{
if(memcmp(str[x],str[rear],sizeof(str[rear]))==0) return false;
x=next[x];
}
next[rear]=head[c];
head[c]=rear;
return true;
}
void show(int front)
{
if(front) show(count[front][0]);
else return;
printf("%c",d[count[front][1]]);
}
void del(int rear,int i)
{
flag=0;
for(int j=1; j<N-1; j++)
for(int k=1; k<M-1; k++)
if(str[rear][j][k]>='1'&&str[rear][j][k]<='3')
{
int c=0;
for(int l=0; l<4; l++)
{
int x=move[l][0]+j,y=move[l][1]+k;
if(str[rear][x][y]==str[rear][j][k]) c=flag=1;
}
if(c) search(str[rear][j][k],j,k,rear);
}
}
void bfs()
{
flag=0;
int rear=1,front=0;
while(rear>front&&rear<NX)
{
flag=0;
for(int i=1; i<N-1&&!flag; i++)
for(int j=1; j<M-1&&!flag; j++)
if(str[front][i][j]>='1'&&str[front][i][j]<='3') flag++;
if(!flag)
{
show(front);
printf("\n");
flag=1;
return;
}
flag=0;
if(count[front][2]<18) for(int i=0; i<4; i++)
{
for(int j=0; j<N; j++)
for(int k=0; k<M; k++)
str[rear][j][k]=str[front][j][k];
flag=0;
if(i==1) while(1)
{
for(int j=1; j<N-1; j++)
for(int k=1; k<M-1; k++)
if(str[rear][j][k]==' ')
{
int l=k+1;
while( l<M-1&&str[rear][j][l]==' ' )l++;
if((str[rear][j][l]>='1'&&str[rear][j][l]<='3')||str[rear][j][l]=='@')
{
flag=1;
str[rear][j][k]=str[rear][j][l];
str[rear][j][l]=' ';
}
else k=l;
}
if(flag)
{
del(rear,i);
if(!flag) break;
}
else break;
}
else if(i==3) while(1)
{
for(int k=1; k<M-1; k++)
for(int j=1; j<N-1; j++)
if(str[rear][j][k]==' ')
{
int l=j+1;
while(l<N-1&&str[rear][l][k]==' ' )l++;
if((str[rear][l][k]>='1'&&str[rear][l][k]<='3')||str[rear][l][k]=='@')
{
flag=1;
str[rear][j][k]=str[rear][l][k];
str[rear][l][k]=' ';
}
else j=l;
}
if(flag)
{
del(rear,i);
if(!flag) break;
}
else break;
}
else if(i==2) while(1)
{
for(int j=1; j<N-1; j++)
for(int k=M-2; k>0; k--)
if(str[rear][j][k]==' ')
{
int l=k-1;
while(l>0&&str[rear][j][l]==' ' )l--;
if((str[rear][j][l]>='1'&&str[rear][j][l]<='3')||str[rear][j][l]=='@')
{
flag=1;
str[rear][j][k]=str[rear][j][l];
str[rear][j][l]=' ';
}
else k=l;
}
if(flag)
{
del(rear,i);
if(!flag) break;
}
else break;
}
else while(1)
{
for(int k=1; k<M-1; k++)
for(int j=N-2; j>0; j--)
if(str[rear][j][k]==' ')
{
int l=j-1;
while( l>0&&str[rear][l][k]==' ') l--;
if((str[rear][l][k]>='1'&&str[rear][l][k]<='3')||str[rear][l][k]=='@')
{
flag=1;
str[rear][j][k]=str[rear][l][k];
str[rear][l][k]=' ';
}
else j=l;
}
if(flag)
{
del(rear,i);
if(!flag) break;
}
else break;
}
int c=hash(rear);
if(insert(c,rear))
{
count[rear][0]=front;
count[rear][1]=i;
count[rear][2]=count[front][2]+1;
rear++;
}
}
front++;
}
}
int main()
{
//freopen("a.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&N,&M);
getchar();
for(int i=0; i<N; i++)
gets(str[0][i]);
memset(next,-1,sizeof(next));
memset(head,-1,sizeof(head));
memset(count,0,sizeof(count));
int c=hash(0);
insert(c,0);
bfs();
if(!flag) printf("-1\n");
gets(s);
}
return 0;
}
10274 - Fans and Gems
最新推荐文章于 2018-09-20 18:42:00 发布