2018ICPC Jiaozuo Station B-Ultraman vs.Aodzilla y Bodzilla (codiciosos)

Pregunta: El poder de ataque del monstruo A es a1, su HP es h1, el poder de ataque del monstruo B es a2, su HP es h2 y el poder de ataque de Ultraman en el i segundo es i. Pregunte antes de matar dos monstruos. Por el daño mínimo que recibe el hombre , encuentre el orden de ataque con el menor orden lexicográfico sobre la premisa del menor valor de daño.

Idea: El valor mínimo de daño no debe ser una pelea entre dos monstruos por un tiempo, debe ser pelear uno tras otro, así que considera si matar a A o B primero.

Primero encuentre el tiempo más corto para matar a AB, el tiempo más corto a para matar A y el tiempo más corto b para matar a B

1. Mata a un primero

(1) En este momento, a a le tomó tiempo matar a A. Si quedan todos-a segundos para matar a B, entonces [1, a] vence a A, [a + 1, todos] vence a B

(2) Si los segundos all-a restantes no son suficientes para matar a B, significa que el poder de ataque se desperdició en un segundo. Si encuentra el valor desperdiciado x , puede presionar B en el x segundo, de modo que puede matar a A en un segundo. Hay desperdicio. Entonces, [1, x-1] le da a A, x le da a B, [x + 1, a] le da a A, [a + 1, all] le da a B

2. Mata a B primero

Se necesita el tiempo de b para matar a B, encontrar el poder de ataque desperdiciado y en el segundo segundo, y usar este poder de ataque del punto y para golpear A antes de golpear B tanto como sea posible, asumiendo que los primeros ak segundos se cambian a presione A (1 + ... + k <= y)

(1) Si los primeros k segundos y el b + 1 segundo hasta todos los segundos son suficientes para matar a A, entonces [1, k] matará a A, [k +1, b] matará a B, [b + 1, todos] Die A

(2) si el segundo y el primero k b + 1 al segundo todos los segundos A no muertos, b descritos en los primeros segundos todavía se han desperdiciado, se asume además la falta z ataque, antes de que el segundo A k retroceda, a la A Para causar un ataque más grande, para asegurar el orden lexicográfico más grande, solo mueva A en el k-ésimo segundo, deje que el k-ésimo segundo golpee a B y el k + z segundo golpee a A. Entonces, [1, k-1] vence a A, [k, k + z-1] vence a B, k + z vence a A, [k + z + 1, b] vence a B, [b + 1, todos] Kill A .

 

Aquí se puede encontrar un problema, por qué el valor de desperdicio en 1 (2) y la diferencia en 2 (2). El valor de desperdicio del monstruo antes de matar es> = la diferencia del monstruo después de matar. Dado que 1 es para golpear Una primera, para asegurar que el orden lexicográfico sea el más pequeño, la posición lo más atrás posible se reemplaza con B, es decir, el valor de desperdicio se usa para acertar B; y en 2, para asegurar el orden lexicográfico más pequeño, Intente hacer que A sea lo más alto posible. El poder de ataque de cambiar a A es lo más pequeño posible, por lo que es una diferencia.

Buena pregunta

Una solución fácil de entender: https://www.cnblogs.com/TheRoadToTheGold/p/14032874.html (La última situación no es del todo correcta, la cambié aquí)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 7;
ll p[N];

int main() {
    for(int i = 1; i < N; ++i) p[i] = p[i - 1] + i;
    int t;
    ll a1, a2, h1, h2;
    scanf("%d", &t);
    while(t--) {
        scanf("%lld%lld%lld%lld", &h1, &h2, &a1, &a2);
        string s1 = "", s2 = "";
        ll ans1 = 0, ans2 = 0;
        ll all = lower_bound(p + 1, p + N, h1 + h2) - p;///总
        ll a = lower_bound(p + 1, p + N, h1) - p;       ///A
        ll b = lower_bound(p + 1, p + N, h2) - p;       ///B
        ///A
        ll now = p[all] - p[a];
        ans1 = a * a1 + all * a2;
        if(now >= h2) {
            string tmp1(a, 'A'), tmp2(all - a, 'B');
            s1 = tmp1 + tmp2;
        }
        else {
            ll lost = p[a] - h1;
            string tmp1(lost - 1, 'A'), tmp2(a - lost, 'A'), tmp3(all - a, 'B');
            s1 = tmp1 + "B" + tmp2 + tmp3;
        }
        ///B
        now = p[all] - p[b];
        ll lost = p[b] - h2, it;
        ans2 = b * a2 + all * a1;
        it = upper_bound(p + 1, p + N, lost) - p - 1;
        ll sum = p[it] + now;
        if(sum >= h1) {
            string tmp1(it, 'A'), tmp2(b - it, 'B'), tmp3(all - b, 'A');
            s2 = tmp1 + tmp2 + tmp3;
        }
        else {
            ll left = h1 - now;
            for(int i = 1; i <= b; ++i) {
                if(left >= 2 * i + 1 || left == i) {
                    left -= i;
                    s2 += "A";
                }
                else s2 += "B";
            }
            string tmp(all - b, 'A');
            s2 += tmp;
        }
        if(ans1 < ans2) cout<<ans1<<' '<<s1<<'\n';
        else if(ans1 > ans2) cout<<ans2<<' '<<s2<<'\n';
        else {
            if(s1 < s2) cout<<ans1<<' '<<s1<<'\n';
            else cout<<ans2<<' '<<s2<<'\n';
        }
    }
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43871207/article/details/114231564
Recomendado
Clasificación