题意:一张图,给出起点和终点,给一个fighting值,每走一步fighting消耗1,并且消耗(abs(H1−H2))/fighting 的 physical power。求起点到终点消耗最小的physical pow。
解:题目上有一句"At the biginning Xiao Ming has a fighting will k,if it turned to 0 Xiao Ming won‘t be able to fight with the devil,that means failure.",原来到终点的时候fighting值可以为0,昨天这里错了一晚上。
思路:优先队列或者普通bfs都可以,这里用优先队列实现。
#include <iostream> #include <algorithm> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <vector> #include <queue> using namespace std; typedef unsigned int uint; typedef long long LL; typedef unsigned long long uLL; const int N = 55; const double PI = acos(-1.0); const double eps = 1e-6; const double INF = 1e9+7; int n, m, k; double csm_ft; char mp[N][N]; struct pt { int x, y; pt(){} pt(int _x, int _y):x(_x), y(_y) {} pt operator + (const pt& add) { return pt(this->x + add.x, this->y + add.y); } bool operator == (const pt& eq) { return (this->x == eq.x && this->y == eq.y); } }; struct node { public: pt p; int ft; double csm; node(){} node(pt _p, int _ft, double _csm):p(_p), ft(_ft), csm(_csm) {} bool operator < (const node& cmp) const { //return ft < cmp.ft; return csm > cmp.csm; } }; priority_queue <node> q; pt bg, ed; double vis[N][N][N]; pt dir[4] = {pt(1, 0), pt(-1, 0), pt(0, 1), pt(0, -1)}; bool in_bound(pt p){ return (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m); } double bfs(int k) { while(!q.empty()) q.pop(); q.push(node(bg, k, 0)); vis[bg.x][bg.y][k] = 0.0f; pt _tp; double s_csm, ans = INF; node t; while(!q.empty()){ t = q.top(); q.pop(); if(t.ft <= 0) continue; if(t.p == ed) { ans = min(ans, t.csm); continue; } for(auto d : dir) { _tp = t.p + d; if(!in_bound(_tp) || mp[_tp.x][_tp.y] == ‘#‘) continue; s_csm = abs(mp[_tp.x][_tp.y] - mp[t.p.x][t.p.y]) * 1. / t.ft; //vis[_tp.x][_tp.y] = min(vis[_tp.x][_tp.y], t.csm); if(t.csm + s_csm >= vis[_tp.x][_tp.y][t.ft - 1]) continue; vis[_tp.x][_tp.y][t.ft - 1] = t.csm + s_csm; q.push(node(_tp, t.ft - 1, t.csm + s_csm)); //printf("%d %d %d %f\n", _tp.x, _tp.y, t.ft - 1, t.csm + s_csm); } } return ans; } int main(){ //freopen("data.in", "r", stdin); int T; cin >> T; while(T--){ cin >> n >> m >> k; for(int i = 0; i < n; ++i) { scanf("%s", mp[i]); for(int j = 0; j < m; ++j) { for(int l = 0; l <= k; ++l) { vis[i][j][l] = INF; } } } scanf("%d%d", &bg.x, &bg.y); scanf("%d%d", &ed.x, &ed.y); bg.x--; bg.y--; ed.x--; ed.y--; double ans = bfs(k); if(ans >= INF) puts("No Answer"); else printf("%.2f\n", ans); } return 0; }
时间: 2024-12-24 22:16:30