前几天18号下午的杭电的ACM网络预赛,看了1008题比较顺眼,呵呵.想了下用A*可以做,恰好前段时间老师讲过.实现了下就过了.为了做题写的有些地方现在看来不完善.打算这几天弄下.
- //附带道路成本的A*
- #include <iostream>
- #include <list>
- #include <math.h>
- #include <algorithm>
- using namespace std;
- const int MAX=0xfffffff;
- char rmap[21][21];
- int vp,vs,vt;
- int R,C,sr,sc,tr,tc;
- int Count,res;
- struct Node
- {
- int f,g,h;
- int r,c;
- Node *parent;
- };
- list<Node> openList;
- list<Node> closeList;
- Node child;
- bool dayu(Node & l,Node & r)
- {
- return l.f>r.f;
- }
- bool check(Node value)
- {
- if (value.r==child.r&&value.c==child.c)
- {
- return true;
- }
- return false;
- }
- bool Reach(int x,int y)
- {
- if (x<0||y<0||x==R||y==C||rmap[x][y]=='@')
- return false;
- return true;
- }
- int GetCost(int x,int y)
- {
- int r;
- if (rmap[x][y]=='T')
- {
- r=vt;
- }
- if (rmap[x][y]=='.')
- {
- r=vs;
- }
- if (rmap[x][y]=='#')
- {
- r=vp;
- }
- return r;
- }
- void Generate(Node &node,int r,int c)
- {
- //不再open和close中
- child.r=r;
- child.c=c;
- list<Node>::iterator posOP=find_if(openList.begin(),openList.end(),check);
- list<Node>::iterator posCL=find_if(closeList.begin(),closeList.end(),check);
- if (posOP==openList.end()&&posCL==closeList.end())
- {
- child.parent=&node;
- child.g=GetCost(r,c)+node.g; //g+1
- child.h=abs(tr-r)+abs(tc-c); //(tr-r)*(tr-r)+(tc-c)*(tc-c)
- child.f=child.g+child.h;
- openList.push_back(child);
- openList.sort(dayu);
- }
- }
- void kuozhan(Node &node)
- {
- if (Reach(node.r,node.c+1))//右
- {
- Generate(node,node.r,node.c+1);
- }
- if (Reach(node.r,node.c-1))// 左
- {
- Generate(node,node.r,node.c-1);
- }
- if (Reach(node.r-1,node.c))// 上
- {
- Generate(node,node.r-1,node.c);
- }
- if (Reach(node.r+1,node.c))// 下
- {
- Generate(node,node.r+1,node.c);
- }
- }
- int main()
- {
- freopen("in.txt","r",stdin);
- int i,j;
- Node temp,best;
- Count=1;
- while (cin>>R>>C)
- {
- res=-1;
- cin>>vp>>vs>>vt;
- for (i=0;i<R;i++)
- for (j=0;j<C;j++)
- {
- cin>>rmap[i][j];
- }
- cin>>sr>>sc>>tr>>tc;
- temp.r=sr;
- temp.c=sc;
- temp.g=0;
- temp.h=abs(tr-sr)+abs(tc-sc); //4反向 //(tr-r)*(tr-r)+(tc-c)*(tc-c)八方向
- temp.f=temp.g+temp.h;
- temp.parent=NULL;
- if (!openList.empty())
- {
- openList.clear();
- }
- openList.push_back(temp);
- closeList.clear();
- while (!openList.empty())
- {
- best=openList.back();
- openList.pop_back();
- if (best.r==tr&&best.c==tc)
- {
- res=best.f;
- break;
- }
- kuozhan(best);
- closeList.push_back(best);
- }
- cout<<"Case "<<Count++<<": "<<res<<endl;
- }
- return 0;
- }
- 输入:
- 4 6
1 2 10
T...TT
TTT###
TT.@#T
..###@
0 1 3 0 - 4 6
1 2 2
T...TT
TTT###
TT.@#T
..###@
0 1 3 0 - 2 2
5 1 3
T@
@.
0 0 1 1 - 输出:
- Case 1: 14
Case 2: 8
Case 3: -1
"T"是树,"."是沙,"#"是路,"@"是石头不能通过,因为最后需要输出的是通过的时间,所以没保存路径.这样parent中保存的也是有错的,呵呵