Aprendizaje de algoritmos de lenguaje C (algoritmo matemático, euclidiano, teoría de la probabilidad)

Hoy solo resolví cuatro preguntas, lo cual es incómodo

resuelto

Una torta de cumpleaños

Reexpresión del problema:

• Lucy y Lily son gemelas y hoy es su cumpleaños. Mamá les compró un pastel de cumpleaños. Ahora la torta se coloca en un sistema de coordenadas cartesianas, el centro de la torta está en (0,0) y el radio de la torta es 100.
• Hay 2N (N es un número entero, 1≤N≤50) cerezas en el pastel. Mamá cortará el pastel por la mitad con un cuchillo (en línea recta, por supuesto). Naturalmente, los gemelos deben ser tratados de manera justa, es decir, las dos mitades del pastel deben tener la misma forma (es decir, la línea recta debe pasar por el centro del pastel), y cada mitad del pastel debe tener N cerezas. ¿Puedes ayudarla?
• Note aquí que las coordenadas (x, y) de la cereza son dos números enteros. Desea dar esta línea en forma de dos números enteros A, B (que representan Ax + By = 0), y A y B están en [−500, 500]. Las cerezas no pueden estar en línea recta. Para cada caso de prueba, hay al menos una solución.

entrar

• La entrada contiene varios casos de prueba. Cada caso de prueba se compone de dos partes: la primera parte da un número N en una línea, y la segunda parte consta de 2N líneas, cada línea tiene dos números, que representan (x, y). Solo hay un espacio entre los dos números. La entrada termina con N = 0.

Salida

• Para cada caso de prueba, genere una línea, dando dos números A y B, con un espacio entre los dos números. Si hay varias soluciones, solo imprima una de ellas.

Análisis de preguntas

• Ingrese N en la primera línea de esta pregunta, lo que significa que hay 2N cerezas en el pastel. Cada una de las siguientes 2N filas da las coordenadas de una cereza Dado que la torta es un círculo con el origen en el centro y un radio de 100, el rango de valores de coordenadas es [-100, 100]. El resultado de esta pregunta es una ecuación en línea recta Ax + By = 0 A y B, el rango es [-500, 500].
• Esta pregunta adopta el método de enumeración, enumera A y B en el rango de [-500, 500] y sustituye las coordenadas de la cereza en la ecuación lineal Ax + By. Si Ax + By es mayor que 0, la cereza está por encima de la línea; si es menor que 0, entonces La cereza está debajo de la línea recta; si es igual a 0, no está permitido porque la cereza no puede estar en línea recta. Enumere hasta obtener la primera solución.

Código fuente

#include <iostream>

using namespace std;

const int LEFT = -500, RIGHT = 500;
const int N = 50;
int x[N * 2], y[N * 2];

int main()
{
    
    
    int n;
    while(~scanf("%d", &n) && n) {
    
    
        n *= 2;

        for(int i = 0; i < n; i++)
            scanf("%d%d", &x[i], &y[i]);

        bool flag = true;
        for(int a = LEFT; a <= RIGHT && flag; a++)
            for(int b = LEFT; b <= RIGHT ; b++) {
    
    
                if(a==0 && b==0 ) continue;
                int i, cnt = 0;     // 统计满足AX+BY>0的点数目
                for(i = 0; i < n; i++) {
    
    
                    if(a * x[i] + b * y[i] > 0) ++cnt;
                    else if(a * x[i] + b * y[i] == 0) break;
                }
                if( i < n) continue;
                if(cnt == n / 2) {
    
    
                    printf("%d %d\n", a, b);
                    flag = false;
                    break;
                }
            }
    }

    return 0;
}

B ¿Es esta integración?

Reexpresión del problema

En la figura, hay un cuadrado ABCD, donde AB = BC = CD = DA = a. Con los cuatro vértices A, B, C, D como centro y a como radio, dibuje cuatro arcos: el arco con A como centro comienza desde el vértice adyacente B y termina en el vértice adyacente D; todos los demás Los arcos se dibujan de manera similar. Como se muestra en la figura, tres áreas de formas diferentes se dibujan en el cuadrado de esta manera, y cada área está representada por un tono diferente. Calcule el área total de las diferentes partes sombreadas.
Inserte la descripción de la imagen aquí

entrar

• A cada línea de entrada se le asigna un número de coma flotante a (0 <a <10000), que representa la longitud de los lados del cuadrado. La entrada termina con EOF.

Salida

• Para cada línea de entrada, genere una línea, dando el área total de tres partes sombreadas diferentes:
dé tres números de punto flotante con tres lugares decimales, el primer número representa el área total del área rayada y el el segundo número representa el área total del área punteada, el tercer número indica el área de las áreas restantes.

Entrada de muestra

0,1
0,2
0,3

Salida de muestra

0,003 0,005 0,002
0,013 0,020 0,007
0,028 0,046 0,016

Resolución del problema

Inserte la descripción de la imagen aquí

Análisis de preguntas

• Esta pregunta da la longitud del lado a de un cuadrado y requiere calcular el área total de tres partes sombreadas diferentes. Como se muestra en la figura, dibuje un triángulo equilátero con líneas auxiliares, y las áreas de las tres partes sombreadas diferentes están representadas por x, y y z.

Código fuente

#include<iostream>
#include<cmath>
using namespace std;
const double pi=acos(-1);
int main() {
    
    
	double a;
	while(cin>>a) {
    
    
		double z=a*a-pi*a*a/6.0-sqrt(3.0)/4.0*a*a;
		double y=(a*a-pi*a*a/4.0-2.0*z);
		double x=(a*a-4.0*y-4.0*z);
		printf("%.3lf %.3lf %.3lf\n",x,y*4.0,z*4.0);
	}
}/*
        double z = r * r * (1 - PI / 6.0 - sqrt(3.0) / 4);
        double y = r * r * (1 - PI / 4.0 ) - 2 * z;
        double x = r * r  * (PI / 2.0 - 1) - 2 * y;
		*/

C División simple

Reexpresión del problema

Inserte la descripción de la imagen aquí
La operación de división entera entre el dividendo ny el divisor d produce el cociente qy el resto r. q es un número entero que maximiza q d tal que q d ≤ n y r = n − q * d.
• Dado un conjunto de números enteros, hay un número entero d tal que cuando cada número entero dado se divide por d, el resto es el mismo.

entrar

• Cada línea de entrada da una secuencia de enteros distintos de cero separados por espacios. El último número de cada línea es 0, que no pertenece a esta secuencia. Hay al menos 2 en una secuencia y como máximo 1000 números; los números en una secuencia no son todos iguales. La última línea de entrada da un solo 0 y el programa no necesita procesar esta línea.

Salida

• Para cada línea de entrada, envíe el número entero más grande de modo que cada entero de la entrada se divida por el número con el mismo resto.

Entrada de muestra

701 1059 1417 2312 0
14 23 17
32122 0 14-22 17-31-124 0
0

Salida de muestra

179
3
3

Resolución del problema

Código fuente

#include <algorithm>
#include<iostream>
using namespace std;
int gcd(int x,int y) {
    
    
	int r;
	while (x%y!=0) {
    
    
		r=x%y;
		x=y;
		y=r;
	}
	return y;
}
int main() {
    
    
	int a1, a;
	while(~scanf("%d", &a1) && a1) {
    
    
		int g = 0;
		while(scanf("%d", &a) == 1 && a) {
    
    
			int d = a - a1;
			if(d) {
    
    
				if(g) g = gcd(g, d);
				else g = d;
			}
			a1 = a;
		}
		printf("%d\n", abs(g));
	}

	return 0;
}

G - hamburguesa

Reexpresión del problema

• Los hijos gemelos de los Clinton, Ben y Bill, celebraron su décimo cumpleaños y la fiesta se llevó a cabo en el restaurante McDonald's en 202 South Broadway en Nueva York. A la fiesta asistieron 20 niños, incluidos Ben y Bill. Ronald McDonald hizo 10 hamburguesas de ternera y 10 hamburguesas con queso. Cuando sirvió a los niños, comenzó con la niña sentada a la izquierda de Bill y Ben sentado a la derecha de Bill. Ronald lanzó una moneda para decidir si la niña comería una hamburguesa de ternera o una hamburguesa con queso. El lado de la cabeza de la moneda es la hamburguesa de ternera y el opuesto es la hamburguesa con queso. Antes de que fuera el turno de Ben y Bill, Ronald repitió el proceso con los otros 17 niños. Cuando Ronald llegó a Ben, ya no tuvo que lanzar una moneda, porque no había hamburguesa con queso, solo dos hamburguesas de ternera.
• Ronald McDonald estaba muy sorprendido por esto, por lo que quería saber la probabilidad de que sucediera este tipo de cosas. Para el proceso anterior, calcule la probabilidad de que Ben y Bill coman la misma hamburguesa. Ronald McDonald siempre cocina la misma cantidad de hamburguesas de carne y hamburguesas con queso.

análisis del problema

Inserte la descripción de la imagen aquí
Como puede ver en la figura anterior, puede usar sin conexión para resolver (la primera vez que usa el método fuera de línea, no capacitado)

Código fuente

#include<iostream>
#include<cmath>
using namespace std;
const int N=5e4+7;
int cas,n;
double p[N];
void solve()
{
    
    
	p[1]=1;
	for(int i=1;i<N-1;++i)
		p[i+1]=(2*i-1)*p[i]/(2*i);
}
int main(){
    
    
	solve();
	cin>>cas;
	while(cas--){
    
    
		cin >>n;
		n/=2;
		printf("%.4lf\n",1-p[n]);
	}
	return 0;
}

Parte no resuelta

D - Problema de Euclides

De Euclides se sabe que para cualesquiera enteros positivos A y B existen tales enteros X e Y que AX + BY = D, donde D es el máximo común divisor de A y B. El problema es encontrar para dados A y B correspondientes a X, Y y D.

Entrada

La entrada constará de un conjunto de líneas con los números enteros A y B, separados por un espacio
(A, B <1000000001).

Salida

Para cada línea de entrada, la línea de salida debe constar de tres números enteros X, Y y D, separados por un espacio.
Si hay varios X e Y de este tipo, debería generar ese par para el que | X | + | Y | es el mínimo. Si hay varios X e Y que satisfacen los criterios mínimos, genere el par para el que X ≤ Y.

Entrada de muestra

4 6
17 17

Salida de muestra

-1 1 2
0 1 17

análisis del problema

Obviamente, este problema debe resolverse con el algoritmo euclidiano extendido

int exgcd(int a, int b, int &x, int &y) {
    
    
	if (b==0) {
    
    
		x=1;
		y=0;
		return a;
	}
	int t=exgcd(b, a%b, x, y);
	int x0=x, y0=y;
	x=y0;
	y=x0-(a/b)*y0;
	return t;

}

Sin embargo, no tengo aire acondicionado y no encuentro el motivo

Código fuente

#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
int exgcd(int a, int b, int &x, int &y) {
    
    
	if (b==0) {
    
    
		x=1;
		y=0;
		return a;
	}
	int t=exgcd(b, a%b, x, y);
	int x0=x, y0=y;
	x=y0;
	y=x0-(a/b)*y0;
	return t;
}
int main() {
    
    
	int a, b, x, y, d;
	while(~scanf("%d%d", &a, &b)) {
    
    
		d = exgcd(a, b, x, y);
		printf("%d %d\n",x,y);
	}
	return 0;
}

F - ¿Qué es la probabilidad?

La probabilidad siempre ha sido una parte integrada de los algoritmos informáticos. Donde los algoritmos determinísticos no han podido resolver un problema en poco tiempo, los algoritmos probabilísticos han venido al rescate. En este problema no se trata de ningún algoritmo probabilístico. Solo intentaremos determinar la probabilidad de ganar de un determinado jugador.
Un juego se juega lanzando un dado como algo (no se debe suponer que tiene seis lados como un dado ordinario). Si un determinado evento ocurre cuando un jugador lanza los dados (como sacar un 3, sacar el lado verde en la parte superior o lo que sea), se declara ganador. Puede haber N tal jugador. Entonces el primero
El jugador lanzará los dados, luego el segundo y por último el N-ésimo jugador y nuevamente el primer jugador y así sucesivamente. Cuando un jugador obtiene el evento deseado, es declarado ganador y el juego se detiene. Tendrá que determinar la probabilidad de ganar de uno (el I-ésimo) de estos jugadores.

Entrada

La entrada contendrá un número entero S (S ≤ 1000) al principio, lo que indica cuántos conjuntos de entradas hay. Las siguientes líneas S contendrán S conjuntos de entradas. Cada línea contiene un entero N (N ≤ 1000) que denota el número de jugadores, un número de coma flotante p que indica la probabilidad de que suceda un evento exitoso en un solo lanzamiento (si el éxito significa obtener 3, entonces p es la probabilidad de obtener 3 en una sola tirada. Para un dado normal la probabilidad de sacar 3 es 1/6), y I (I ≤ N) la serie del jugador cuya probabilidad de ganar se va a determinar (el número de serie varía de 1 a N). Puede asumir que no se proporcionará ningún valor de probabilidad § inválido como entrada.

Salida

Para cada conjunto de entradas, escriba en una sola línea la probabilidad de que el I-ésimo jugador gane. El
número de punto flotante de salida siempre tendrá cuatro dígitos después del punto decimal como se muestra en la
salida de muestra .

Entrada de muestra

2
2 0,166666 1
2 0,166666 2

Salida de muestra

0,5455
0,4545

análisis del problema

Inserte la descripción de la imagen aquí
Aunque sustituí la fórmula, no tengo aire acondicionado y no puedo encontrar la razón

Código fuente

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
    
    
	int N,i,n;
	double p;
	scanf("%d",&N);
	for(int j=0; j<N; j++) {
    
    
		cin >>n >>p >>i;
		float proba =(pow((1-p),i-1)*p/(1-pow((1-p),n)));
		printf("%.4f\n",proba);
	}
}

Todavía quedan muchos problemas hoy, no sé cuándo tendré tiempo para resolverlos

Supongo que te gusta

Origin blog.csdn.net/seekerzhz/article/details/112910421
Recomendado
Clasificación