链接:https://www.nowcoder.net/acm/contest/76/G
来源:牛客网
老子的意大利炮呢
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制: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 ",ans); 135 } 136 137 138 return 0; 139 }