老子的意大利炮呢

链接:https://www.nowcoder.net/acm/contest/76/G
来源:牛客网

老子的意大利炮呢
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

自攻打过太原县城以后,李云龙这意大利炮就使用的越发的顺手了,指哪打哪也是绝不含糊,于是小野队长开始疯狂打击独立团炮兵营,为了锻炼士兵移动意大利炮的能力,李团长开始给炮兵营进行特训,众(wo)所(xia)周(bian)知(de),意大利炮可由炮管,车轮,炮弹三部分组成,现在李团长在洋村设立阵地,分别把炮管,车轮,炮弹放在三个不同的地方,每一部分的重量不同,所以运输的速度也不相同。团长说:你谁有能耐最快把这意大利炮组装好然后运到我面前,老子就赏他半斤地瓜烧,和尚听了乐坏了,但是他不知道怎么才能使时间最快,你能帮帮他么?

零件只要拿起,就不能放下,所以说不存在在a点拿起,b点放下再去取别的零件一说。默认和尚1秒走一个单位距离,并且只能向上下左右四个方向走,假设和尚现在拿着炮管,那么他每走一单位距离则需要(t1 + 1)秒,如果再拿上车轮,那么他现在每走一步则需要(t1 + t2+1)秒的时间,以此类推。点可以重复经过,路过有零件的点时,可以选择拿或者不拿。

输入描述:

第一行给定两个整数n, m代表地图大小,(1<=n, m <= 100);接下来n行每行有m个由‘#’和‘.’组成的字符,’#’代表墙,’.’代表路,和尚功夫高,可以自己或者带着零件FQ(不论墙多厚),但是组装好意大利炮之后就必需得走路了。地图画好之后,接下来一行有10个整数sx,sy,x1, y1, x2, y2, x3, y3, ex, ed(都小于100)代表五个点,分别是起始点,炮管的位置,车轮的位置,炮弹的位置,李团长的位置(终点), 五个点保证不同。最后一行三个整数t1, t2, t3,(都大于等于1,小于100),分别代表炮管,车轮,炮弹每走一单位距离需要的时间。题目保证数据合法。

输出描述:

输出一个整数并换行,代表和尚完成任务所需要的最短时间。题目保证有解。
示例1

输入

3 5
##.##
.#.#.
##.##
1 3 2 1 2 3 2 5 3 3 
1 5 4

输出

34

说明

对于第一组样例,我们发现只有在2号零件也就是车轮的位置组装完才能运回到李团长的位置,所以最优解为:起始点->1号零件 –> 3号零件-> 2号零件->李团长
路线为(1,3),(2,3),(2,2),(2,1),(2,2),(2,3),(2,4),(2,5),(2,4),(2,3),(3,3)。
答案为34。

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define LL long long
  7  
  8 using namespace std;
  9  
 10  
 11 struct node
 12 {
 13     int x,y;
 14 }p[10];
 15 struct state
 16 {
 17     int x,y,s;
 18 };
 19 int n,m;
 20 int w[5];
 21 char a[110][110];
 22 int vis[110][110];
 23 int dir[4][2] = {0,1,1,0,-1,0,0,-1};
 24 int e[6][6];
 25  
 26 void bfs(int x,int y,int u)
 27 {
 28     memset(vis,0,sizeof(vis));
 29     queue<state> q;
 30     state t,next;
 31     t.x = x;
 32     t.y = y;
 33     t.s = 0;
 34     vis[x][y] = 1;
 35     q.push(t);
 36     while(!q.empty())
 37     {
 38         t = q.front();
 39         q.pop();
 40         for(int i=0;i<4;i++)
 41         {
 42             if(p[i].x == t.x && p[i].y == t.y)
 43             {
 44                 e[u][i] = t.s;
 45             }
 46         }
 47         for(int i=0;i<4;i++)
 48         {
 49             int tx = t.x + dir[i][0];
 50             int ty = t.y + dir[i][1];
 51             if(tx < 1 || ty < 1 || tx > n || ty > m)
 52                 continue;
 53             if(vis[tx][ty] == 1)
 54                 continue;
 55             vis[tx][ty] = 1;
 56             next.x = tx;
 57             next.y = ty;
 58             next.s = t.s + 1;
 59             q.push(next);
 60         }
 61     }
 62 }
 63  
 64 void bfs2(int x,int y,int u)
 65 {
 66     memset(vis,0,sizeof(vis));
 67     queue<state> q;
 68     state t,next;
 69     t.x = x;
 70     t.y = y;
 71     t.s = 0;
 72     vis[x][y] = 1;
 73     q.push(t);
 74     while(!q.empty())
 75     {
 76         t = q.front();
 77         q.pop();
 78         if(p[4].x == t.x && p[4].y == t.y)
 79         {
 80             e[u][4] = t.s;
 81             return;
 82         }
 83         for(int i=0;i<4;i++)
 84         {
 85             int tx = t.x + dir[i][0];
 86             int ty = t.y + dir[i][1];
 87             if(tx < 1 || ty < 1 || tx > n || ty > m)
 88                 continue;
 89             if(vis[tx][ty] == 1 || a[tx][ty] == '#')
 90                 continue;
 91             vis[tx][ty] = 1;
 92             next.x = tx;
 93             next.y = ty;
 94             next.s = t.s + 1;
 95             q.push(next);
 96         }
 97     }
 98 }
 99 int main(void)
100 {
101     int i,j,k;
102     while(scanf("%d%d",&n,&m)==2)
103     {
104         memset(e,0x3f,sizeof(e));
105         for(i=1;i<=n;i++)
106             scanf("%s",a[i]+1);
107         for(i=0;i<5;i++)
108             scanf("%d%d",&p[i].x,&p[i].y);
109         for(i=1;i<=3;i++)
110             scanf("%d",&w[i]);
111         for(i=0;i<4;i++)
112         {
113             bfs(p[i].x,p[i].y,i);
114             bfs2(p[i].x,p[i].y,i);
115         }
116         int ans = 1e9;
117         for(i=1;i<=3;i++)
118         {
119             for(j=1;j<=3;j++)
120             {
121                 if(j == i)
122                     continue;
123                 for(k=1;k<=3;k++)
124                 {
125                     if(k == i || k == j)
126                         continue;
127                     if(e[k][4] > 10000)
128                         continue;
129                     int tmp = e[0][i] + e[i][j]*(w[i]+1) + e[j][k]*(w[i]+w[j]+1) + e[k][4]*(w[i]+w[j]+w[k]+1);
130                     ans = min(ans,tmp);
131                 }
132             }
133         }
134         printf("%d\n",ans);
135     }
136  
137  
138     return 0;
139 }
View Code

 

posted on 2018-02-11 21:11  蔡军帅  阅读(84)  评论(0编辑  收藏  举报