http://www.cnblogs.com/ts65213/p/3145843.html
棋盘上有几个箱子,可以找个空地,放置'推子'。然后横向或竖向推动,直到遇到箱子,将箱子数减1,推到下一格,若下一格也有箱子,则两者相加。 推子在第一个箱子的原位置。
推子和箱子之间至少有一个空格才能撞动箱子。
dfs,注意保存的每一个状态是什么。。
别人的好代码:
char c[30][30];
int a[30][30];
int n,m,count,flag;
int dir[2][4]={{ -1, 1, 0, 0 },
{ 0, 0,-1, 1 }};
char dd[]={'U','D','L','R'};
char d[10000];
bool can(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m)return true;
return false;
}
void Readdata(){
count=0; flag=0;
for(int i=0;i<n;i++){
cin>>c[i];
for(int j=0;j<m;j++){
if(c[i][j]=='.')a[i][j]=0;
else {
a[i][j]=(c[i][j]-'a')+1;
count+=a[i][j];
}
}
}
}
void dfs(int i,int j,int cnt){
if(cnt>=count){flag=1;d[cnt]='\0';return;}//要有在后面加上那个'\0',, 否则会wa。。
for(int k=0;k<4;k++){
if(flag)return;
int x=i+dir[0][k],y=j+dir[1][k];
if( !can(x,y) || a[x][y] ) continue;
while( can(x,y) &&!a[x][y] ) {
x+=dir[0][k]; y+=dir[1][k];
}
if(!can(x,y)) continue;
d[cnt]=dd[k];
int u=a[x][y];
if(u>1&&!can(x+dir[0][k],y+dir[1][k]))continue;
if(u>1) a[x+dir[0][k]][y+dir[1][k]]+=u-1;
a[x][y]=0;
dfs(x,y,cnt+1); if(flag)return;
if(u>1) a[x+dir[0][k]][y+dir[1][k]]-=u-1;
a[x][y]=u;
}
}
int ax,ay;
void solve(){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(a[i][j])continue;
//for(int k=0;k<4;k++){
if(flag)return;
//int x=i+dir[0][k], y=j+dir[1][k],xx=x+dir[0][k],yy=y+dir[1][k];
//if(can(xx,yy)&&a[xx][yy]&&!a[x][y]) {
ax=i; ay=j;
dfs(i,j,0);
//}
//}
}
}
int main(){
while(cin>>m>>n){
Readdata();
solve();
if(flag){
cout<<ax<<endl<<ay<<endl;
int i=0;
while(d[i]!='\0')cout<<d[i++];
cout<<endl;
}
}
return 0;
}