2012-08-11 我的第一个A*算法:
四处看A*算法。。还是有一点没有弄明白就是那个当已经在列表中的时候再次进入的时候怎么去更新。
这道题。。有点难开始的时候不会位压缩,去看了一个别人的代码。所以感谢一下。这位高手。写了一个bfs(),500多ms。
看了A*算法后,用A*算法去改进了一下。跑到了360ms很高兴。。所以写了一下,作为学A*算法的一个纪念;
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 char sign[21][21][16385]; 7 char map[21][25]; 8 int m,n,L,k; 9 int maxstep; 10 int minstep; 11 struct node 12 { 13 int xi,xj; 14 }; 15 node pt[10]; 16 int f[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 17 struct stem 18 { 19 int xi,xj; 20 int state; 21 int h,f,g; 22 bool operator<(const stem &a)const 23 { 24 return f>a.f; 25 } 26 }u,v,w; 27 void setmap(node *_pt) 28 { 29 int i; 30 for(i=1;i<L;i++) 31 { 32 map[_pt[i].xi][_pt[i].xj]=1; 33 } 34 } 35 void clearmap(node *_pt) 36 { 37 int i; 38 for(i=1;i<L;i++) 39 map[_pt[i].xi][_pt[i].xj]=0; 40 } 41 int bfs(char stone[][25]) 42 { 43 priority_queue<stem>q; 44 w.xi=1; 45 w.xj=1; 46 w.g=0; 47 w.f=pt[0].xi+pt[0].xj-2; 48 w.h=pt[0].xi+pt[0].xj-2; 49 q.push(w); 50 int i,j; 51 while(!q.empty()) 52 { 53 u=q.top(); 54 q.pop(); 55 for(i=0;i<4;i++) 56 { 57 v.xi=u.xi+f[i][0]; 58 v.xj=u.xj+f[i][1]; 59 if(v.xi<1||v.xi>n||v.xj<1||v.xj>m)continue; 60 if(stone[v.xi][v.xj])continue; 61 stone[v.xi][v.xj]=1; 62 v.g=u.g+1; 63 v.h=pt[0].xi-v.xi+pt[0].xj-v.xj; 64 v.f=v.g+v.h; 65 if(v.xi==pt[0].xi&&v.xj==pt[0].xj)return v.f; 66 q.push(v); 67 } 68 } 69 return -1; 70 } 71 void getmaxmin() 72 { 73 char stone[21][25]; 74 memcpy(stone,map,sizeof(map)); 75 minstep=bfs(stone); 76 if(minstep==-1)return ; 77 setmap(pt); 78 memcpy(stone,map,sizeof(map)); 79 maxstep=bfs(stone); 80 clearmap(pt); 81 if(maxstep==-1)maxstep=0xffff; 82 return ; 83 } 84 int getstate() 85 { 86 int stem;int i; 87 88 stem=0; 89 for(i=1;i<L;i++) 90 { 91 stem<<=2; 92 if(pt[i].xi>pt[i-1].xi)stem|=0; 93 else if(pt[i].xi<pt[i-1].xi) stem|=1; 94 else if(pt[i].xj>pt[i-1].xj) stem|=2;//以前面一位作为标准 95 else 96 stem|=3; 97 } 98 99 return stem; 100 } 101 void getcord(int x,int y,int state) 102 { 103 pt[0].xi=x; 104 pt[0].xj=y; 105 int manx; 106 int step; 107 int i;manx=3; 108 for(i=1;i<L;i++) 109 { 110 step=(state>>((L-i-1)*2))&manx; 111 if(step==0) x++; 112 else if(step==1) x--; 113 else if(step==2) y++; 114 else if(step==3) y--; 115 pt[i].xi=x; 116 pt[i].xj=y; 117 } 118 return ; 119 } 120 int bfs() 121 { 122 int i; 123 priority_queue<stem>q; 124 w.xi=pt[0].xi; 125 w.xj=pt[0].xj; 126 w.g=0; 127 w.f=pt[0].xi+pt[0].xj-2; 128 w.h=pt[0].xi+pt[0].xj-2; 129 w.state=getstate(); 130 q.push(w); 131 while(!q.empty()) 132 { 133 u=q.top();q.pop(); 134 getcord(u.xi,u.xj,u.state); 135 setmap(pt); 136 for(i=0;i<4;i++) 137 { 138 v.xi=u.xi+f[i][0]; 139 v.xj=u.xj+f[i][1]; 140 if(v.xi<1||v.xi>n||v.xj<1||v.xj>m)continue; 141 if(map[v.xi][v.xj])continue; 142 if(u.g+1+v.xi+v.xj-2>maxstep)continue; 143 v.state=((u.state>>2)|(i<<(L-2)*2)); 144 if(sign[v.xi][v.xj][v.state])continue; 145 sign[v.xi][v.xj][v.state]=1; 146 v.g=u.g+1; 147 v.h=v.xi+v.xj-2; 148 v.f=v.g+v.h; 149 if(v.xi==1&&v.xj==1)return v.f; 150 q.push(v); 151 } 152 clearmap(pt); 153 } 154 return -1; 155 } 156 int main() 157 { 158 int i; 159 int cas; 160 cas=0; 161 while(scanf("%d%d%d",&n,&m,&L)&&(n+m+L)) 162 { 163 cas++; 164 int x,y; 165 maxstep=0; 166 minstep=0; 167 for(i=0;i<L;i++) 168 { 169 scanf("%d%d",&pt[i].xi,&pt[i].xj); 170 } 171 scanf("%d",&k); 172 memset(map,0,sizeof(map)); 173 memset(sign,'\0',sizeof(sign)); 174 for(i=0;i<k;i++) 175 { 176 scanf("%d%d",&x,&y); 177 map[x][y]=1; 178 } 179 printf("Case %d: ",cas); 180 getmaxmin(); 181 if(pt[0].xi==1&&pt[0].xj==1)printf("0\n"); 182 else if(minstep==-1)printf("-1\n"); 183 else if(minstep==maxstep)printf("%d\n",minstep); 184 else printf("%d\n",bfs()); 185 } 186 return 0; 187 }
最后就是继续努力。。