[题解] HDU 2128 Tempter of the Bone II(迭代加深)

来源:互联网 发布:mysql eq ref 编辑:程序博客网 时间:2024/04/28 05:01

HDU 2128 Tempter of the Bone II(迭代加深)

  刚刚看到这道题目时,很开心啊:好水啊~这不就是一个BFS么,太简单了。
  然而,当我发现一个点可以重复访问并且有可能更优时,我掐指一算,WTF,这能过?果断转向DFS,但是将所有结果全部找出来再判断绝对的TLE。怎么办?
  So,这就成为了结合BFS与DFS优点的迭代加深算法发威的时候了!
  好好好,既然知道算法了,来一发题解装13,然而,等待着我的是:WA WA WA WA WA…
  WTF?为毛?
  经过三个小时的细心查找,原来是题目描述不清。Doggie炸掉一个墙是需要在原地停留一秒的!!!(泪如雨下)好吧就这样吧,交上去终于开心的AC了。
  来讲讲迭代算法。迭代算法其实就是在普通DFS的外面套一层搜索下界,以保证搜索得到的是最优解。特别适合那些不知道搜索下界有可能无限搜搜搜搜搜的题目。具体内容让我们来看代码。
代码如下:

#include <bits/stdc++.h>using namespace std;char MAP[10][10];int sum[10][10];int mo[4][2]={{1,0},{0,1},{0,-1},{-1,0}};int n,m,stx,sty,sgx,sgy;bool flag=0;void search(int x,int y,int num,int total,int depth) {  int qwe,i;char ch;  if(total==depth) {   //前面的搜索可以保证没有可行解,so如果在最后一层搜到结果就输出啦~    if(MAP[x][y]=='D') flag=1;    return;  }  int nx,ny;  sum[x][y]=num;  //sum用来保存每一个点的最大炸药数,因为炸药当然是越多越好啦!其实就是为了方便判重。。  if(abs(x-sgx)+abs(y-sgy)>depth-total) return; //这里是曼哈顿局距离的可行性剪枝  for(i=0;i<=3;i++) {    nx=x+mo[i][0];    ny=y+mo[i][1];    if(nx<0 || nx>=n || ny<0 || ny>=m || sum[nx][ny]>=num) {continue;}    if(MAP[nx][ny]=='X' && num>=1) { //如果手头上还有炸药就把墙炸了      MAP[nx][ny]='.';      qwe=sum[nx][ny];      search(nx,ny,num-1,total+2,depth);      MAP[nx][ny]='X';      sum[nx][ny]=qwe;      if(flag)       {return;}     }    else if(MAP[nx][ny]=='.' || MAP[nx][ny]=='D' || MAP[nx][ny]=='S') {      qwe=sum[nx][ny];      search(nx,ny,num,total+1,depth);      sum[nx][ny]=qwe;      if(flag)       {return;}    }    else if(MAP[nx][ny]>='1' && MAP[nx][ny]<='9') { //将炸药“入库”      ch=MAP[nx][ny];      qwe=sum[nx][ny];      MAP[nx][ny]='.';      search(nx,ny,num+ch-'0',total+1,depth);      MAP[nx][ny]=ch;      sum[nx][ny]=qwe;      if(flag)       {return;}    }  }  return;}bool input() { //输入部分大家都懂的哈  int i,j,k;  memset(MAP,0,sizeof(MAP));  memset(sum,0,sizeof(sum));  scanf("%d%d\n",&n,&m);  if(n==0 && m==0) return false;  for(i=0;i<n;i++) {    for(j=0;j<m;j++) {      scanf("%c",&MAP[i][j]);      if(MAP[i][j]=='S') {        stx=i;        sty=j;        MAP[i][j]='.';      }      if(MAP[i][j]=='D') {        sgx=i;        sgy=j;      }    }    scanf("\n");  }  for(i=1;i<=100;i++) {    //为了方便,我将迭代部分也放在了这里    for(j=0;j<n;j++) {   //每次i自增,就让迭代的层数往下一层      for(k=0;k<m;k++) {//i超过100应该就没有解啦(我猜的)        sum[j][k]=-1;      }    }    search(stx,sty,0,0,i);    if(flag) {printf("%d\n",i);break;}  }  return true;}int main() {  int i;  while(1) {    flag=0;    if(!input()) {break;}    if(flag) continue;    printf("-1\n");  }  return 0;}


最后来一波数据(来自HDU)
Input:
6 5
S.XX1
X.1X1
XX.X.
XXXXX
XXXXX
XXXDX
2 6
S.1XXD
1..XXX
4 4
S1X1
XXXX
XXDX
XXXX
6 2
S1
..
1X
XX
XX
DX
0 0
Output
17
9
8
9

                                            From:ChliencePS:有问题或者闲的蛋疼的朋友可以发邮件至steve_chl@qq.com或者私信我,欢迎骚扰O(∩_∩)O~~