冒险者分队是人气 MMORPG《最终幻想 14》里的一个游戏系统。玩家通过招募 NPC (非玩家角色)组成小队完成特定任务后可以获取丰厚的奖励。
由于完成任务有能力的要求,因此我们需要对 NPC 进行一定的训练。NPC 组成的小队会有三个属性:体能、心智,以及战术,玩家可以选择以下的两种训练课程之一对小队进行训练:
提升其中一个属性 40,降低其他两个属性各 20;
提升其中两个属性 20,降低剩下一个属性 40。
如果在选择的训练课程后有任意一个属性小于 0,那么训练会失败,属性不会发生变化。
为了完成特定任务,现在给定小队的初始属性和目标属性,请回答是否有可能通过一定的训练,使得小队的属性正好达到目标属性的值,如果可以的话,最少的次数是多少?
输入格式:
输入第一行是一个正整数 T (≤10 ^ 5 ),表示有多少组询问。
接下来的 T 组询问,每组询问有两行,每行三个非负整数,第一行为小队初始的属性,第二行为需要达成的目标属性。
所有属性值均大于等于 0,小于等于 2×10 ^ 9 。
输出格式:
如果目标属性无法通过训练达到,输出一行 −1,否则输出一个整数,表示达到目标属性的最少训练次数。
输入样例:
4
25 30 35
65 10 15
100 200 300
200 180 220
100 100 100
0 0 0
777 888 999
777 888 999
结尾无空行
输出样例:
1
3
-1
0
结尾无空行
思路:首先做差,差值%20有余数的肯定不行。然后直接把三个差值/20,简化问题。另外不管是-1,-1,+2还是-2,+1,+1,这三个数%3的值都是1,每次也只会使得三个差值同时+1或+2,因此原来这三个差值必%3相等,否则-1,然后我们就判完了非法情况。
然后我也不知道怎么构建最优解,于是我就看了官方题解。。。。首先让我们使得a < b < 0 < c,我们以1,1,-2作用于三者,那么b会首先变成0,然后我们再以两个操作2,-1,-1和1,1,-2组合成3,0,-3作用于a和c,就能构建出最优解。或许有人要问如果a或c不能被3整除怎么办?事实是不会的,由于b=0,并且三者对3同余,因此三者%3都等于0,是可以整除的。于是代码就写好了。还是很难想的。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define endl '\n'
void solve(){
int a,b,c,x,y,z;
cin >> a >> b >> c >> x >> y >> z;
int dx = a - x,dy = b - y,dz = c - z;
if (dx % 20 || dy % 20 || dz % 20 || a + b + c != x + y + z){
cout << -1 << endl;
return;
}
dx /= 20,dy /= 20,dz /= 20;
int mod = (dx % 3 + 3) % 3;
if ((dy % 3 + 3) % 3 != mod || (dz % 3 + 3) % 3 % 3 != mod){
cout << -1 << endl;
return;
}
int num = 0;
num += (dx > 0) + (dy > 0) + (dz > 0);
if (num == 2) dx = -dx,dy = -dy,dz = -dz;
x = min({dx,dy,dz}),z = max({dx,dy,dz}),y = dx + dy + dz - x - z;//排序
int res = 0;
res += -y,x -= y,z += y * 2,y = 0;
res += z / 3 * 2;
cout << res << endl;
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--) solve();
}