A - Integer Moves
题意
给定一组坐标,采用每次只能移动整数个单位,问需要花多少步走到该点上去
题解
当已经在这个点上的时候,我们不需要走
当两点距离已经为整数的时候,我们可以走一步
否则,我们可以走两步,可以用三角形的两边之和大于第三边来解释,我们到达那个点,一定可以构造两个整数使得从00出发到那个点为两个整数
Code
int T;
int x, y;
void solve(){
cin >> x >> y;
int t = sqrt(x * x + y * y);
if(x == 0 && y == 0)
cout << 0 << endl;
else if(t * t == x * x + y * y)
cout << 1 << endl;
else
cout << 2 << endl;
}
B - XY Sequence
题意
给定一个n,B,x,y
构造这样一个数组满足
- a i = a i − 1 + x a_i=a_{i-1}+x ai=ai−1+x或 a i = a i − 1 − y a_i=a_{i-1}-y ai=ai−1−y
- a i ≤ B a_i\leq B ai≤B
问数组之和最大是多少
题解
无敌经典贪心放
尽可能的大
Code
int T;
int n, B, x, y;
void solve(){
cin >> n >> B >> x >> y;
vector<ll> v;
v.pb(0);
for (int i = 1; i <= n; i++){
if(v[i - 1] + x <= B)
v.pb(v[i - 1] + x);
else
v.pb(v[i - 1] - y);
}
ll summ = 0;
for(auto i : v){
// cout << i << ' ';
summ += i;
}
// cout << endl;
cout << summ << endl;
}
C - Bracket Sequence Deletion
题意
给定一个括号序列,每次只能删除前缀,前缀满足条件其一即可:
- 是一个长度大于等于2的回文
- 是一个合法的括号序列
问按照这个规则删除,操作数和最后剩余的字符长度是多少
题解
这个题的分析pzr大佬总结的很详细:https://zhuanlan.zhihu.com/p/485742160
而我的思路就是硬模拟
Code
int T;
int n;
string s;
bool pd(string t){
for (int i = 0; i < t.size() / 2; i ++){
if(t[i] != t[t.size() - 1 - i])
return 0;
}
return 1;
}
// 您的任务是找出您将对给定字符串执行的操作的数量,以及字符串中剩余字符的数量
void solve(){
cin >> n >> s;
int l = 0;
int cnt = 0;
int last = 0;
string tmp;
if(n == 1){
cout << 0 << ' ' << 1 << endl;
return;
}
for (int i = 0; i < s.size(); i++){
if(s[i] == '('){
l++;
}
else{
l--;
if(l == 0){
cnt++;
last = i;
l = 0;
tmp = "";
continue;
}
l = max(0, l);
}
tmp += s[i];
if(tmp.size() >= 2 && s[i] == tmp[0] && pd(tmp)){
last = i;
cnt++;
tmp = "";
l = 0;
}
}
if(cnt)
cout << cnt << ' ' << s.size() - last - 1 << endl;
else
cout << 0 << ' ' << s.size() << endl;
}
D - For Gamers. By Gamers.
题意
现有n 种兵种,每种有单位招募代价、攻击力、生命值三个数值。需回答 m 次询问——每次询问给出魔王的攻击、生命,问在以下条件下,击败魔王至少需要花费多少代价?
- 只能选择一种兵种的士兵招募
- 任意士兵不能在战斗中死亡
- 魔王与士兵并非回合制战斗,造成伤害是连续的。
每一次的金币是独立的
题解
每次只能选择一种士兵进行购买,那么每次实际上就是买k个士兵会得到k倍的攻击力加持
我们假设对于某一种怪物 D m , H m D_m, H_m Dm,Hm,需要的士兵战斗力和生命值为 D s , H s D_s,H_s Ds,Hs,那么则需要满足 H m D s < H s D m \frac{H_m}{D_s}<\frac{H_s}{D_m} DsHm<DmHs
则 H m ∗ D m < H s ∗ D s H_m*D_m<H_s*D_s Hm∗Dm<Hs∗Ds,那么也就是满足当前啊士兵所做出的贡献应当为 H s ∗ D s H_s*D_s Hs∗Ds,也就是花费 c c c金币获得了 H s ∗ D s H_s*D_s Hs∗Ds的收益
那么我们可以预处理出来我们要用的 C C C金币以内中不同的金币能够产生多大的价值,然后再根据每一个怪物来查询即可
我们定义 m a x v [ i ] maxv[i] maxv[i]为花费i金币得到的最大价值
那么对于每一个士兵我们都处理一下价值,最后取max保存到数组中即可
Code
int T;
int n, m, k;
int maxv[M];
void solve(){
cin >> n >> m;
for (int i = 1; i <= n; i++){
int c, d, h;
cin >> c >> d >> h;
maxv[c] = max(maxv[c], d * h);
}
for (int i = 1; i <= m; i++){
for (int j = i * 2; j <= m; j += i){ // 买的钱数
maxv[j] = max(maxv[j], maxv[i] * (j / i)); // 当前的最大价值与买i号士兵j/i=k个获得的价值取max
}
}
for (int i = 1; i <= m; i++){ // 如果花费的少还能得到更大的价值就更新
maxv[i] = max(maxv[i], maxv[i - 1]);
}
cin >> k;
while(k--){
int d, h;
cin >> d >> h;
if(maxv[m] <= d * h){ // 最大价值都不行就肯定不行
cout << -1 << endl;
}
else{
int id = upper_bound(maxv, maxv + m + 1, h * d) - maxv;
cout << id << ' ';
}
}
}