1005 - Secuencia numérica

Inserte la descripción de la imagen aquí

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a,b;
long long n;
int f(int a,int b,long long n){
    
    
	if(n==1)
		return 1;
	else if(n==2)
		return 1;
 	else
		return (a*f(a,b,n-1)+b*f(a,b,n-2))%7;
}
int main()
{
    
    
	while(cin>>a>>b>>n){
    
    
		if(a==0 && b==0 && n==0)
			break;
		cout<<f(a,b,n)<<endl;
	}
	return 0;
}

Pronto, escribir el código anterior es una función recursiva simple, resultó ser enviado con confianza Límite de memoria excedido, en el análisis final, el número de iteraciones superó con mucho el límite de memoria, el código no es lo suficientemente bueno
enrollado en CSDN, se encontró que era un poco cruel La pregunta se debe principalmente a que es un poco controvertida. Algunas personas lo han hecho pero no pueden explicar por qué. También utilizo mi conocimiento superficial para explorar: (ver dónde está la ley)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int f(int a,int b,int n)
{
    
    
	if(n==1 || n==2)
		return 1;
    else
		return (a*f(a,b,n-1)+b*f(a,b,n-2))%7;
}
int main()
{
    
    
	int a,b,n;
	while(scanf("%d%d%d",&a,&b,&n) !=EOF){
    
    
		if(a==0 && b==0 && n==0)
			break;
		for(int i=1;i<=n;i++)
			cout<<f(a,b,i);
	}
	return 0;
}

La computadora tarda mucho en calcular durante la prueba:

Inserte la descripción de la imagen aquí

Lo cerré cuando había menos de 50 personas y salió un poco lento, pero nos sorprendió mucho descubrir que había un patrón (1123160 ...), 16 ciclos en un ciclo. En cuanto a por qué, debería dale una explicación a un matemático y prueba algunos conjuntos más:
Inserte la descripción de la imagen aquí
14 Un bucle
Inserte la descripción de la imagen aquí
Esto es un poco extraño, ¿verdad? . . .
Aquí, primero intentamos dar el código de 'AC' basado en el intercambio de internautas:

#include<iostream>
#include<cstdio>
using namespace std;
int a,b,n,c[100];
int main()
{
    
    
	while(cin>>a>>b>>n){
    
    
		if(a==0 && b==0 && n==0)
			break;
		c[1]=1;
		c[2]=1;
		for(int i=3;i<=48;i++){
    
    
			c[i]=(a*c[i-1]+b*c[i-2])%7;
		}
		cout<<c[n%48]<<endl;
	}
	return 0;
}

Se acabó, pero aún no ha terminado: "
Probemos primero los dos ejemplos de prueba con el código anterior: (a = 1, b = 1 en el frente, lo siguiente es a = 1, b = 2)
Inserte la descripción de la imagen aquí

Es un período y el período es 6,
así que llegamos a una conclusión: ¡el período está ahí, pero no se puede medir por 48! En mi ejemplo anterior, un ciclo es 14 y uno comienza desde el segundo. Obviamente, no se puede resolver con el llamado código AC. Solo se puede decir que esto es una broma. El ciclo de casos de prueba de Hangdian es exactamente un factor de 48, por lo que, afortunadamente, si desea obtener la respuesta correcta, debe encontrar otra manera:

Matriz de potencia rápida

#include<iostream>
using namespace std;
struct M{
    
    
	int m[2][2];
};
int A,B;
M mul(M a,M b){
    
    
	M ans;
	for(int i=0;i<2;i++){
    
    
		for(int j=0;j<2;j++){
    
    
			ans.m[i][j] = 0;
			for(int k=0;k<2;k++)
				ans.m[i][j] = (ans.m[i][j]+a.m[i][k]*b.m[k][j]%7)%7;
		}
	}
	return ans;
}
M quick(long long b){
    
    
	M ans,c;
	ans.m[0][0] = ans.m[1][1] = 1;
	ans.m[0][1] = ans.m[1][0] = 0;
	c.m[0][0] = A,c.m[0][1] = B,c.m[1][0] = 1,c.m[1][1] = 0;
	while(b){
    
    
		if(b&1) ans = mul(ans,c);
		b >>= 1;
		c = mul(c,c);
	}
	return ans;
}
int main(){
    
    
	long long n;
	while(cin>>A>>B>>n){
    
    
		if(A==0&&B==0&&n==0) break;
		if(n<=2) cout<<"1"<<endl;
		else{
    
    
			M a = quick(n-2);
			cout<<(a.m[0][0]+a.m[0][1])%7<<endl;
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/interestingddd/article/details/113870720
Recomendado
Clasificación