Hoof Paper Scissors Minus One
Explicación
Para resolver esto, hay que revisar cuántos pares posibles de gestos existen en los que uno de los dos gestos puede vencer a ambos gestos de Elsie, el de la izquierda y el de la derecha.
Casos de prueba 1 a 6
Esto se puede resolver creando primero un arreglo 2D que indique si el gesto puede ser vencido por el gesto , derivado de la «pirámide de victorias» dada en la entrada.
vector<vector<bool>> beatenBy(n, vector<bool>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
char state;
cin >> state;
if (state == 'L') {
beatenBy[i][j] = true;
} else if (state == 'W') {
beatenBy[j][i] = true;
}
}
}n, m = map(int, input().split())
beats = [[False for i in range(n)] for j in range(n)]
for i in range(n):
state = input()
for j in range(len(a)):
if state[j] == "W":
beats[i][j] = True
elif state[j] == "L":
beats[j][i] = TrueCon esto, una fuerza bruta de por cada partida funciona. Aquí hay un ejemplo:
for (int myL = 0; myL < n; myL++) {
for (int myR = 0; myR < n; myR++) {
if ((beatenBy[l][myL] && beatenBy[r][myL]) ||
(beatenBy[l][myR] && beatenBy[r][myR]))
possible++;
}
}for myL in range(n):
for myR in range(n):
if (beats[myL][l] and beats[myL][r]) or (beatsy[myR][l] and beats[myR][r]):
possible += 1Casos de prueba 7 a 12
Para optimizar el cálculo por partida de a , hace falta una serie de optimizaciones que, al final, se convierten en una sola fórmula.
Optimización 1:
Se puede notar que si myL ya es capaz de vencer tanto a l como a r, no hace falta probar todos los myR.
for (int myL = 0; myL < n; myL++) {
if (beatenBy[l][myL] && beatenBy[r][myL]) {
possible += n;
} else {
for (int myR = 0; myR < n; myR++) {
if (beatenBy[l][myR] && beatenBy[r][myR]) possible++;
}
}
}for myL in range(n):
if beats[myL][l] and beats[myL][r]:
possible += n
else:
for myR in range(n):
if beats[myR][l] and beats[myR][r]:
possible += 1Optimización 2:
Si es cuántos gestos de los pueden vencer tanto a l como a r de Elsie, entonces podemos asumir que esta comprobación:
for (int myL = 0; myL < n; myL++) {
if (beatenBy[l][myL] && beatenBy[r][myL]) possible += n;es equivalente a
possible += x * n;y la cláusula else se ejecuta veces, y suma posibilidades.
possible += x * (n - x)Con esto, se obtiene que la fórmula de los pares ganadores es . Implementar directamente esta fórmula permite resolver cada partida en .
Nótese que se puede derivar una fórmula equivalente basada en conteo:
2 * x * n - x ** 2Implementación
Complejidad temporal:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
// Read the win triangle
vector<vector<bool>> beatenBy(n, vector<bool>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
char state;
cin >> state;
if (state == 'L') {
beatenBy[i][j] = true;
} else if (state == 'W') {
beatenBy[j][i] = true;
}
}
}
// Read Elsie's moves
for (int i = 0; i < m; i++) {
int l, r;
cin >> l >> r;
l--;
r--;
int x = 0;
for (int a = 0; a < n; a++) {
if (beatenBy[l][a] && beatenBy[r][a]) x++;
}
int possible = x * n + x * (n - x); // equation is explained above
cout << possible << "\n";
}
}n, m = map(int, input().split())
beats = [[False for i in range(n)] for j in range(n)]
for i in range(n):
state = input()
for j in range(len(state)):
if state[j] == "W":
beats[i][j] = True
elif state[j] == "L":
beats[j][i] = True
for _ in range(m):
l, r = map(int, input().split())
x = 0
for my_symbol in range(n):
if beats[my_symbol][l - 1] and beats[my_symbol][r - 1]:
x += 1
print(2 * x * n - x**2) # this is also equivalent to x*n + x*(n-x)