HZNUOJ 2803 prefijo bidimensional y + gcd

Sharpshooter JoneySun (versión fácil)

Límite de tiempo: 1 s Límite de memoria: 256 MB
Envío: 146 AC: 32 Puntuación: 100,00

Descripción La
versión fácil y la versión un poco dura solo difieren en el rango de datos

JoneySun estaba atrapado en una prisión dividida por una cuadrícula de 1 × 1 por la malvada esposa. La malvada esposa vio los chistes de JoneySun en algún lugar de la prisión. Afortunadamente, JoneySun tenía un arma en la mano. Desafortunadamente, es la esposa la que ha dominado la técnica del doppelganger.

Creemos que esta prisión es una cuadrícula de 2n × 2m. JoneySun está atrapado en el medio. A excepción de JoneySun, hay un avatar de esposa en las otras intersecciones de la cuadrícula. El alcance del arma de JoneySun es infinito, si la bala golpea al clon, el clon desaparecerá y la bala seguirá viajando en línea recta. Si la bala golpea el cuerpo de la esposa, JoneySun destruirá la esposa. JoneySun quería saber el número máximo de balas necesarias para destruir a una esposa.


Un entero T en la primera línea de Entrada (1≤T≤100) indica que hay T grupos de entradas

Dos enteros n, m (1≤n, m≤103) en la segunda línea, vea el título para el significado

Muestras
entrada
1
1 1
salida
8
Sugerencia

Como se muestra en la figura, el punto rojo indica la ubicación de JoneySun y el punto azul indica el clon de wifepie. Se necesitan hasta 8 balas para destruir todos los clones de wifipie.

Preste atención a la complejidad, T es muy grande, pruebe todas las optimizaciones metafísicas que se le ocurran

Solución del problema: el significado del problema es averiguar cuántos rayos no superpuestos desde el punto de origen hasta cada vértice, es decir, determinar si mcd (i, j) es igual a 1 o mcd (i, j) = d, mcd Si (i / d, j / d) es igual a 1, si es igual a 1, significa que es un lado factible. Como todo rectángulo es simétrico, se puede transformar en un problema de cuadrante para resolver. Debido a que el problema tiene 100 conjuntos de datos de prueba, la complejidad es relativamente grande, por lo que la solución violenta será T, por lo que consideramos usar un prefijo bidimensional y preprocesamiento, y luego O (1) para la consulta.
El código de CA es el siguiente:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<map>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<set>
#include<cctype>
#include<string>
#include<stdexcept>
#include<fstream>
#include<sstream>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 10000007
#define debug() puts("what the fuck!")
#define dedebug() puts("what the fuck!!!")
#define ll long long
#define ull unsigned long long
#define speed {
    
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); };
using namespace std;
const double PI = acos(-1.0);
const int maxn = 1e6 + 50;
const int N = 35;
const int INF = 0x3f3f3f3f;
const int inf = 0xfffffff;//比INF小,防止累加爆int
const double esp_0 = 1e-6;
const double gold = (1 + sqrt(5)) / 2;
int gcd(int x, int y) {
    
    
	return y ? gcd(y, x % y) : x;
}
int n, m;
int dp[1020][1020];
int main() {
    
    
	mem(dp, 0);
	for (int i = 1; i <= 1010; ++i) {
    
    
		for (int j = 1; j <= 1010; ++j) {
    
    
			int step = gcd(i, j);
			if (step == 1)dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + step;//如果是可行边,则加上改点的值
			else {
    
    
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];//如果不是可行边,则不加
			}
		}
	}
	int t;
	scanf("%d", &t);
	while (t--) {
    
    
		scanf("%d%d", &n, &m);
		int ans = dp[n][m] * 4 + 4;
		printf("%d\n", ans);
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_40924271/article/details/107872288
Recomendado
Clasificación