SLON ---- Método recursivo infijo diferente de la solución positiva

Descripción del Título

SLON es un estudiante travieso. Para calmarlo, la maestra le dio un problema de matemáticas:

Dada la expresión A, A contiene variables x y +, -, *, (,) estos símbolos, los paréntesis aparecen en pares, un operador aritmético corresponde a dos operandos, no pueden aparecer (-5) o (4+ -5) Etc. , el signo de multiplicación no se puede omitir, y x en la expresión A solo puede ser una expresión de primer orden:

Expresión razonable: A = 5 + x ∗ (3 + 2) o x + 3 ∗ x + 4 ∗ (5 + 3 ∗ (2 + x − 2 ∗ x)).

Expresión irrazonable: A = 5 ∗ (3 + x ∗ (3 + x)) o x ∗ (x + x ∗ (1 + x)).

Cuando A% M == P, el menor x

ingresar

Ingrese una expresión A en la primera línea, (1 ≤ | A | ≤ 100000).

Ingrese dos números enteros P (0 ≤ P ≤ M −1) y M (1 ≤ M ≤ 1000000) en la segunda línea.

Producción

Genere el valor de x no negativo más pequeño (0 ≤ x ≤ 1000000).

Entrada de muestra 1

5 + 3 + x

9 10

Salida de muestra 1

1

Entrada de muestra 2

20 + 3 + x

0 5

Salida de muestra 2

2

Entrada de muestra 3

3 * (x + (x + 4) * 5)

1 7

Salida de muestra 3

1


Ideas

Esta pregunta se hizo originalmente con un sufijo, amigos que son firmes en moralidad, por favor vea la solución correcta del maestro.

Primero pensemos: A es una expresión de primer orden (una función).

Como se mencionó en matemáticas de la escuela secundaria, una función lineal se puede expresar como kx + b. Por ejemplo, el ejemplo uno se puede expresar como x + 8, el ejemplo dos se puede expresar como x + 23 y el ejemplo tres se puede expresar como 18x +60.

Entonces solo se requieren k y b, y como 0 ≤ x ≤ 1000000, puede enumerarse violentamente (también puede usar la expansión de Europa, que es más rápida).

El siguiente paso es la esencia de esta pregunta: reduce la expresión compleja A del ladrón a kx + b.

Primero podemos usar la idea de bloque: debido a que la suma y la resta es el cálculo final, entonces divida A en varias partes y sume la suma, luego, ¿puede cada parte expresarse en la forma de kx + b? (Obviamente)

Use la función ins () para cambiar una fórmula a kx + b. Dado que no se sabe en cuántas partes se divide A, es mejor usar un vector de matriz dinámica para almacenar cada parte. Cuando se encuentra un número o una x, si está precedido por "+" o "-", súmelo (añade un signo menos para restar); si va precedido por "*", multiplica el último dígito de la matriz por él.

Cuando encuentra "(", ingresa de forma recursiva, convierte la expresión ins () entre corchetes en a kx + b, y luego realiza las mismas operaciones que antes.

Esta operación de multiplicación necesita una discusión especial: cuando se multiplican dos kx + b, uno de los k es cero (porque el problema garantiza que el número de x es 1), por lo que equivale a multiplicar k y b en un lado por a constante.

Un punto más, debido a que el título no indica qué tan grande es el número en A, puede estallar mucho tiempo, debe modulo m mientras opera, sin afectar el resultado.

Para operaciones y detalles específicos, consulte el código a continuación

Código

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#define ll long long
using namespace std;
ll k,b,p,m;
int l;
string ss;
struct itn{
	ll k,b;
	itn(){}itn(ll K,ll B){
	k=(K+m)%m,b=(B+m)%m;
	}
	itn operator+(const itn&c){return itn(k+c.k,b+c.b);}
	itn operator*(const itn&c){
		if(k==0)return itn(c.k*b,c.b*b);
		else return itn(k*c.b,b*c.b);
	}
};
char s;
itn ins(){
	vector<itn>g;
	itn an=itn(0,0);
	int f=0;
	while(l<=ss.length()&&s&&s!=')'){
		if(s>='0'&&s<='9'){
			ll x=0;
			while(l<=ss.length()&&s>='0'&&s<='9')x=(x*10+s-'0')%m,s=ss[l++];//l=ss.length()时返回的为'\0'
			if(f==0)g.push_back(itn(0,x));
			else if(f==1)g.push_back(itn(0,-x));
			else {
				int o=g.size()-1;
				g[o]=g[o]*itn(0,x);
			}
		}
		else if(s=='x'){
			if(f==0)g.push_back(itn(1,0));
			else if(f==1)g.push_back(itn(-1,0));
			else {
				int o=g.size()-1;
				g[o]=g[o]*itn(1,0);
			}
			if(l<=ss.length())s=ss[l++];
		}
		else if(s=='+'){
			f=0;
			if(l<=ss.length())s=ss[l++];
		}
		else if(s=='-'){
			f=1;
			if(l<=ss.length())s=ss[l++];
		}
		else if(s=='*'){
			f=2;
			if(l<=ss.length())s=ss[l++];
		}
		else if(s=='('){
			if(l<=ss.length())s=ss[l++];
			itn x=ins();
			if(f==0)g.push_back(x);
			else if(f==1)g.push_back(itn(-x.k,-x.b));
			else {
				int o=g.size()-1;
				g[o]=g[o]*x;
			}
			if(l<=ss.length())s=ss[l++];
		}
	}
	for(int i=0;i<g.size();i++)an=an+g[i];
	return an;
}
int main()
{
	//freopen("slon.in","r",stdin);
	//freopen("slon.out","w",stdout);
	cin>>ss;
	scanf("%lld%lld",&p,&m);
	s=ss[l++];
	itn a=ins();
	k=a.k,b=a.b;
	//printf("A=%lldx+%lld\n",k,b);
	for(ll x=0;x<=1000000;x++)
		if(x*k+b>=0&&(x*k+b)%m==p){
			printf("%lld\n",x);
			return 0;
		}
	puts("100000");
	return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43960287/article/details/97132073
Recomendado
Clasificación