Prueba escrita de Lenovo 811

Prueba escrita de Lenovo 811

Tema 1

Ingrese una cadena de longitud n que contenga solo letras en inglés y el subíndice comienza en 1. Realiza las siguientes operaciones en esta cadena Q veces, y la i-ésima operación es la siguiente:
l_i, r_i, k, lo que significa copiar la cadena original con el subíndice l_i, l_i + 1, ..., r_i; después de eso: si k= 0, pégalo al principio de la cadena; si k=1, pégalo al final de la cadena.
Debe generar la cadena obtenida después de las operaciones Q.

Descripción de entrada
La primera línea contiene dos números enteros positivos n, Q (1 es menor o igual que n, Q es menor o igual que 2x10^4).
La segunda línea es una cadena de longitud n que contiene solo letras en inglés.
La tercera línea contiene Q enteros positivos: l_1, l_2, ..., l_Q; la
cuarta línea contiene Q enteros positivos: r_1, r_2, ..., r_Q; la
quinta línea contiene Q enteros positivos: k_1, k_2, .. ., k_Q.
Garantía de datos: 1 es menor o igual que l_i es menor o igual que r_i es menor o igual que n, 0 es menor o igual que r_i-l_i <10, k_i pertenece a {0,1} y el el rango de entrada es legal.

Descripción de salida
Genera una línea, indicando la cadena final.

Entrada de muestra
7 2
Xabcdez
2 1
4 7
0 1

Salida de muestra
abcXabcdezXabcdez

#include <iostream>
#include <string>
#include <vector>

int main() {
    
    
    int n, q;
    std::cin >> n >> q;  // 输入字符串长度n和操作次数q
    
    std::string original_str;
    std::cin >> original_str;  // 输入原始字符串

    std::vector<int> l_values(q);
    std::vector<int> r_values(q);
    std::vector<int> k_values(q);

    for (int i = 0; i < q; ++i) {
    
    
        std::cin >> l_values[i];  // 输入每次操作的起始下标l
    }

    for (int i = 0; i < q; ++i) {
    
    
        std::cin >> r_values[i];  // 输入每次操作的结束下标r
    }

    for (int i = 0; i < q; ++i) {
    
    
        std::cin >> k_values[i];  // 输入每次操作的粘贴位置k
    }

    std::string result = original_str;  // 初始化结果字符串为原始字符串

    for (int i = 0; i < q; ++i) {
    
    
        int l = l_values[i];
        int r = r_values[i];
        int k = k_values[i];

        // 从原始字符串中复制指定范围的子串
        std::string copied_str = original_str.substr(l - 1, r - l + 1);

        if (k == 0) {
    
    
            // 如果粘贴位置k为0,则将复制的子串粘贴在结果字符串的前面
            result = copied_str + result;
        } else {
    
    
            // 如果粘贴位置k为1,则将复制的子串粘贴在结果字符串的末尾
            result = result + copied_str;
        }
    }

    std::cout << result << std::endl;  // 输出最终得到的字符串

    return 0;
}

Tema 2

Defina f(A) para representar el número de elementos en la secuencia después de realizar la operación única en la secuencia A.
La operación única se refiere a la secuencia obtenida al combinar elementos adyacentes e idénticos en un solo elemento y luego organizarlos en el orden relativo de la secuencia original.
Por ejemplo,
[1,1,1,2,2,3,3,1] después de la secuencia de operación única es [1,2,3,1]; [1,2,3,3,2,1] El la secuencia después de la operación única es [1,2,3,2,1]; [1,1,1,1,1] la secuencia obtenida después de la operación única es [1].
Ahora, ingrese una secuencia S de longitud n, debe dividirla en k segmentos para que cada segmento no esté vacío y debe maximizar la suma de los valores de la función f de todos los segmentos. Solo necesita generar este valor máximo.

Descripción de entrada
La primera línea son dos enteros positivos n, k (1 es menor o igual que k es menor o igual a la quinta potencia de n es menor o igual a 10); la segunda línea son n enteros positivos a_1
, a_2...a_n separados por espacios (1 es menor o igual que a_i es menor o igual a 10000), que representa la secuencia de entrada S.

Descripción de salida
Genera un número entero que representa el valor máximo buscado.

Entrada de muestra
8 3
1 1 1 2 2 3 3 1
Salida de muestra
6
Explicación de muestra
Dividido de la siguiente manera:
[1], [1 1 2 2 3], [3 1]
El valor de la función del primer párrafo es 1 y la función valor del primer párrafo El valor de la función del segundo segmento es 3 y el valor de la función del tercer segmento es 2, sumando 6. Se puede demostrar que no existe mayor esquema que éste.

Idea:
programación dinámica

Usando dos capas de bucles, el bucle exterior atraviesa todos los elementos y el bucle interior atraviesa todos los números de segmento posibles. En el bucle interno, considere dividir los primeros p elementos en segmentos j-1 y los elementos restantes como el segmento j. Para encontrar el esquema de partición más grande, usamos una variable maxVal para registrar la suma de los valores f de cada partición posible y actualizamos el valor máximo a dp [i] [j] después de que finaliza el ciclo interno.

Finalmente, la salida dp[n][k] es el valor máximo buscado, que indica la suma de los valores máximos de f cuando toda la secuencia se divide en k segmentos.

La función f se utiliza para calcular el número de elementos de la secuencia después de la operación única, su función en el código es calcular el valor f de cada división, ayudando así al cálculo de la programación dinámica.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 定义函数 f,计算序列 segment 经过 unique 操作后的元素个数
int f(const vector<int>& segment) {
    
    
    vector<int> uniqueSegment;
    for (int i = 0; i < segment.size(); ++i) {
    
    
        if (i == 0 || segment[i] != segment[i - 1]) {
    
    
            uniqueSegment.push_back(segment[i]);
        }
    }
    return uniqueSegment.size();
}

int main() {
    
    
    int n, k;
    cin >> n >> k;  // 输入序列长度 n 和划分段数 k
    
    vector<int> sequence(n);
    for (int i = 0; i < n; ++i) {
    
    
        cin >> sequence[i];  // 输入序列的元素
    }

    // 使用动态规划,dp[i][j] 表示前 i 个元素划分为 j 段时的最大值
    vector<vector<int>> dp(n + 1, vector<int>(k + 1, 0));

    for (int i = 1; i <= n; ++i) {
    
    
        for (int j = 1; j <= k; ++j) {
    
    
            int maxVal = 0;
            vector<int> segment;
            for (int p = i; p >= 1; --p) {
    
    
                segment.push_back(sequence[p - 1]);
                // 在前 p-1 个元素划分为 j-1 段的基础上,加上当前划分的段的 f 值
                maxVal = max(maxVal, dp[p - 1][j - 1] + f(segment));
            }
            dp[i][j] = max(dp[i][j], maxVal);  // 更新 dp[i][j]
        }
    }

    cout << dp[n][k] << endl;  // 输出最大值

    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_47895938/article/details/132307816
Recomendado
Clasificación