#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
ll t, x, y, mn, ans;
ll c1, c2, c3, c4, c5, c6;
int main() {
scanf("%d", &t);
while(t--) {
//输入终点
scanf("%lld%lld", &y, &x);
//输入各个方向的值
scanf("%lld%lld%lld%lld%lld%lld", &c1, &c2, &c3, &c4, &c5, &c6);
//更新各个方向的值
c1 = min(c1, c6 + c2);
c2 = min(c2, c1 + c3);
c3 = min(c3, c2 + c4);
c4 = min(c4, c3 + c5);
c5 = min(c5, c4 + c6);
c6 = min(c6, c5 + c1);
//划分四个区域进行讨论
if(x >= 0 && y >= 0) {
ans = min(x, y) * c1 + (x - min(x, y)) * c2 + (y - min(x, y)) * c6;
} else if(x >= 0 && y < 0) {
ans = -y * c3 + x * c2;
} else if(x <= 0 && y > 0) {
ans = -x * c5 + y * c6;
} else {
ans = min(-x, -y) * c4 + (-x - min(-x, -y)) * c5 + (-y - min(-x, -y)) * c3;
}
printf("%lld\n", ans);
}
}
这道题的大致思路是,先更新各个方向的值,使得每次移动时,累加的值更小。
然后就是处理怎么走的问题了大致分成4个分块:
对于这几个区间我们要进行不同的走法:
对于左上角的区域,我们要要先往c6走再往c5走
对于右上角的区域,我们要往c1走然后分类讨论,接下来可能往c6走,也可能往c2走,此时需要分类。
对于左下角的区域,我们要往c4走然后分类讨论,接下来可能往c5走,也可能往c3走,此时需要分类。
对于右下角的区域,我们要要先往c3走再往c2走
情况和分区整理好了代码就好写了,一定要注意正负号和分区的边界问题。