Hang Dian oj 1006 Tick and Tick solución de problemas personales

Hang Dian oj 1006 Tick and Tick solución de problemas personales

Primero, publiqué la pregunta original en el sitio web oficial.
Título original de Hang Dian
Al principio vi esta pregunta y pensé que era otra pregunta relacionada con el agua. Después de mirar más de cerca la pregunta, me di cuenta de que esta pregunta es más una prueba de matemáticas. Realmente me hizo luchar durante mucho tiempo. Estas son algunas de mis ideas:

Idea 1: método de simulación de violencia

Quizás la mayoría de las personas usan segundos para simular un reloj, y luego determinan la posición de las manecillas de las horas y los minutos según la cantidad de segundos, y luego acumulan el tiempo. Aquí puede usar 1s, 0.1s, 0.01s o incluso 0.001s como la unidad de simulación de tiempo, pero en realidad hay Dos desventajas principales:
1. La unidad de tiempo es pequeña y el número de simulaciones es grande.
2. Si la precisión no es suficiente, mantenga 3 lugares decimales.
No estoy usando segundos para simular, sino que estoy usando los grados recorridos por la manecilla de segundos para simular, lo que ahorra tiempo y conversión de grados.
Lo que necesita saber es: la velocidad de la manecilla de segundos = 60 × la velocidad de la manecilla de los minutos = 720 × la velocidad de la manecilla de las horas
Aquí está el código que escribí (presentado como la primera idea, falló en oj):

#include<bits/stdc++.h>//这个头文件也称万能头,包括c和c++的很多头文件
using namespace std;
int main()
{
    
    
    int n;
    double a=0,t=0,miao,fen,shi;
    cin>>n;
    while(n<=120&&n>=0)
    {
    
    
        //模拟时钟
        while(shi<360)
        {
    
    
            t+=0.45;//t是计算总时间,以0.45°为单位累加
            miao=t-(int)t/360*360;//这里因为t为double型,用不了%,所以自己写了一个类似与%的东西。
            fen=t/60-(int)t/60/360*360;
            shi=t/720;
            if(abs(miao-fen)>=n&&miao-fen+360>=n&&fen+360-miao>=n)//这里的判断略显繁琐,其实可以用define宏来简化代码。
               if(abs(miao-shi)>=n&&miao-shi+360>=n&&shi+360-miao>=n)
                  if(abs(fen-shi)>=n&&fen-shi+360>=n&&shi+360-fen>=n)
                     a+=0.45;//a用来统计开心时间
        }
        printf("%.3lf\n",a/t*100);//c++的小数点控制不大会用,方便起见用了c的printf函数
        cin>>n;
        a=t=shi=0;//这里需要重置数据
    }
    cin.get();
    cin.get();//这里用两个cin.get();来暂停界面,保留窗口,不影响oj的判断
}

En realidad, hay muchos detalles del proceso de procesamiento,
como: se escriben tres si, por ejemplo, abs (miao-fen)> = n, es para juzgar la diferencia entre el grado de miao y fen, y aquí se usa abs porque el grado de fen es posible Más que miao (relativo a la posición inicial). Además, los siguientes (miao-fen + 360)> = ny fen-miao + 360 se utilizan para calcular otro ángulo.

Luego, este 0.45 se ha depurado varias veces. Al principio, usé 0.01. Después de ejecutarlo, descubrí que el tiempo de ejecución era demasiado largo, por lo que lo cambié a un valor mayor y se convirtió en 1. Aunque la muestra de prueba era correcta, se envió cuando se envió. Incorrecto (precisión insuficiente).
Pegue la imagen enviada:
Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquí
puede ver la respuesta incorrecta aquí, y el tiempo de ejecución no es pequeño.
Así que intenté cambiar el tiempo por precisión.
El resultado es como se muestra en la figura:
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Luego intente aumentarlo a 0.5: disminuirlo
Inserte la descripción de la imagen aquí
(corazón cansado), 0.45: ¡
Inserte la descripción de la imagen aquí
resulta que no hay un buen algoritmo oj lo niega!
Entonces comencé Baidu y descubrí que muchos otros blogueros usaban la forma de resolver ecuaciones, pero todos estaban publicados por el código. No lo entendí, o era demasiado largo para leer. Quería rendirme, pero luego lo pensé. Nunca va a suceder si no lo haces, así que bien podría intentarlo de nuevo.
Hoy, después de pasar todo el día, finalmente noqueé, que es la idea 2.

Idea 2: Resuelve la ecuación, calcula el intervalo entre los dos que cumplen las condiciones y finalmente toma la intersección y fusiona los intervalos.

charla:

Déjame hablar de toda mi lucha (puedes saltarte si no quieres verla, la tontería personal del blogger): Al
principio, pensé en la idea de usar problemas matemáticos, es decir, primero dejar que el minutero y la manecilla de las horas produzcan un clip n Ángulo, calcule el tiempo en este momento y luego determine la posición del segundero sobre esta base, aquí está el código que entregué a la mitad:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    int n,q=0;
    double miao=0,fen,shi,t1,t2,t3,t4,ans=0;
    cin>>n;
    while(n<=120&&n>=0)
    {
    
    
        //解多次方程
        while(720/11*(n+q*360)<259200)//用度数来解方程
        {
    
    
           t1=720/11*(n+q*360);q++;//解出分针与时针满足条件时的时间
           t2=720/11*(q*360-n);//t1,t2用来确定分针和时针开心的边界,t3,t4用来确定秒针分别与时针和分针的开心边界
           //用for循环寻找在t1-t2该区间的miao的范围
           t3=t4=0;
           
 
           for(int i=0;t3<259200;i++)
           {
    
    
               t3=(n+(i*360))*720/719;
               if(t1<t3&&t3<t2)break;
           }
           for(int i=0;t4<259200;i++)
           {
    
    
               t4=(360*(i+1)-n)*720/719;
           }      
        }
        
    }
    cin.get();
    cin.get();
}

Pero luego descubrí que estaba mal. T3 y t4 están al frente, y ¿qué hay detrás? T3 y t4 tienen que ir a la parte pública, que puede superponerse con la última t3 o la última vez t4, etc ...
Entonces, decidí usar la función de computadora: Capaz de almacenar grandes cantidades de datos para resolver todos los dolores de cabeza

Tema:

De hecho, mirando hacia atrás en esta pregunta, encontrará que lo que nos pidió que hiciéramos es calcular todos los intervalos de tiempo que cumplen con las condiciones, luego sumarlos y finalmente calcular la proporción del tiempo total.
Porque las primeras 12 horas y las últimas 12 horas de las 24 horas del día La situación horaria es la misma, así que use 12 horas como tiempo total.En
primer lugar, el marco general para esta pregunta debería ser calcular el intervalo que cumple directamente las condiciones (no puede cumplir las tres condiciones a la vez. Calcular)
Por lo tanto, debe ser el intervalo entre la manecilla de la hora y la manecilla de los segundos, el intervalo entre la manecilla de la hora y la manecilla de los minutos, y el intervalo entre la manecilla de los minutos y la manecilla de las horas, y finalmente tomar la intersección.
Primero pegue el código y luego explique:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    int n,s1=0,s2=0,s3=0,s4=0;
    double ms[2000],fs[30],fm[2000],h1[2000],ans=0;
    cin>>n;
    while(n<=120&&n>=0)
    {
    
    
        for(int i=0;(n+360*i)*720.0/719<259200;i++)
        {
    
    
            ms[s1++]=(n+360*i)*720.0/719;
            ms[s1++]=((i+1)*360-n)*720.0/719;
        }

        for(int i=0;(n+360*i)*720.0/11<259200;i++)
        {
    
    
            fs[s2++]=(n+360*i)*720.0/11;
            fs[s2++]=((i+1)*360-n)*720.0/11;
        }

        for(int i=0;(n+360*i)*60.0/59<259200;i++)
        {
    
    
            fm[s3++]=(n+360*i)*60.0/59;
            fm[s3++]=((i+1)*360-n)*60.0/59;
        }
        //合并fs和fm,并入h1之中
        for(int i=0;i<s2;i+=2)
          for(int j=0;j<s3&&fm[j]<fs[i+1];j+=2)
          {
    
    
              if(fm[j+1]>fs[i])
              {
    
    
                  h1[s4++]=max(fm[j],fs[i]);
                  h1[s4++]=min(fm[j+1],fs[i+1]);
              }
          }
        //合并h1和ms,并入fm
        s3=0;
        for(int i=0;i<s4;i+=2)
        for(int j=0;j<s1&&ms[j]<h1[i+1];j+=2)
        {
    
    
            if(ms[j+1]>h1[i])
            {
    
    
                fm[s3++]=max(ms[j],h1[i]);
                fm[s3++]=min(ms[j+1],h1[i+1]);
            }
        }
        for(int i=0;i<s3;i+=2)ans+=fm[i+1]-fm[i];
        printf("%.3f\n",ans/259200*100);
        s1=s2=s3=s4=ans=0;
        cin>>n;
    }
    cin.get();
    cin.get();
}

46 ms está bien
1.
tipo int:
n se usa para almacenar los datos de entrada
s1 se usa para almacenar el número de elementos de la matriz ms (se espera que sea 1440, use 2000 para propósitos de seguro)
s2 almacena la cantidad de elementos en la matriz fs (se espera que sea 24, use 30)
s3 almacena la matriz fm El número de elementos de (1440 estimado, use 2000)
s4 almacena el número de elementos de la matriz h1 (1440 estimado, use 2000)
2.
Matriz doble: la
matriz ms almacena los intervalos donde la manecilla de los segundos y la manecilla de la hora cumplen las condiciones (ms es la abreviatura de segundos)
y así sucesivamente. La
matriz h1 se usa para almacenar el intervalo para la primera combinación (dos por dos se combinan dos veces, originalmente debería haber dos La matriz se usa para almacenar el intervalo de fusión, pero primero fusioné fs y fm, por lo que la matriz fm es inútil durante la segunda fusión y se puede vaciar como la matriz de intervalo final. Además, la matriz fs tiene muy pocos valores, así que fusiona primero La matriz fs se puede repetir unas pocas veces menos)
double ans se usa para almacenar happy time.
3. (La parte central)
¿Cómo calcular eso es cómo resolver la ecuación?

En realidad, es muy simple. Tomemos n = 90 °, la manecilla de los segundos y la manecilla de las horas como ejemplo. Aquí utilizo la ecuación de la secuencia de grados, es decir, establezco el grado de la manecilla de los segundos ax, luego la primera vez que se cumple la condición:
xx / 720 = ¿Qué pasa si
la manecilla de los segundos de 90 sobrepasa la manecilla de las horas un círculo más?
Xx / 720 = 90 + 360
¿Qué pasa con otro círculo?
Xx / 720 = 90 + 360 × 2

xx / 720 = 90 + 360 × i
Entonces la solución es x = (90 + 360 × i) × 720/719.

De hecho, hay otra situación:
es la manecilla de la hora y la manecilla de los segundos.
Cuando la manecilla de los segundos excede la manecilla de la hora y persigue la manecilla de la hora, la primera vez que se cumplen las condiciones:
x / 720 + 360-x = 90, lo
mismo ocurre después de i círculo:
x / 720 + 360 × ix = 90
resuelve ax = (360 × i-90) × 720/719.

Luego, puede analizar la manecilla de los segundos y la manecilla de los minutos, la manecilla de los minutos y la manecilla de las horas de la misma manera.
Finalmente, combine dos por dos y acumule el tiempo ans. Luego recuerde restablecer los datos después de generar la relación para el siguiente cálculo.

(PD: comentario para apoyar al blogger, son las 12:30 de la noche, tengo un poco de sueño ~)

Adjuntar mi borrador (uno al azar)
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_35598074/article/details/109232379
Recomendado
Clasificación