P8789 [蓝桥杯 2022 国 B] 填空问题 题解

· · 题解

A 2022

采用 DP 求解。设 dp_{i,j} 表示选 j 个数总和为 i 的方案数。

编写的函数如下。

int work1()
{
    long long dp[2025][11]={0};   // dp[i][j]表示选j个数总和为i的方案数
    dp[0][0]=1;
    int i,j,k;
    for (i=1;i<=2022;i++)
    {
        for (j=10;j>=1;j--)
        {
            for (k=i;k<=2022;k++)
            {
                dp[k][j]+=dp[k-i][j-1];
            }
        }
    }
    printf("%lld\n",dp[2022][10]);
}

执行上面的处理函数,输出结果为:379187662194355221

B 钟表

将表盘的 0 点(或 12 点)作为起点,整个表盘转一圈 360 度,用 60 个刻度线分成 60 格,每 1 格就是 6 度。

时钟每走 1 个小时,时针走 5 格,转 30 度;分针走 60 格,转 360 度(正好走一圈,相当转 0 度);秒针走 3600 格,转 21600 度(走了 60 圈,也相当转 0 度)。

时钟每走 1 分钟,分针走 1 格,转 6 度;时针走 5/60 格,转 1/2 度;秒针走 60 格,相当转了 0 度。

时钟每走 1 秒,秒针走 1 格,转 6 度;分针走 1/60 格,转 1/10 度;时针走 5/3600 格,转了 1/120 度。

因此,对于任意一个时刻 hh:mm:ss,有

时针转的度数为 30\times hh + mm/2 + ss/120

分针转的度数为 6\times mm + ss/10

秒针转的度数为 6\times ss

计算出各指针转的度数后,它们之间的差值就是它们的夹角。

用三重循环对每一个时刻进行枚举,找到满足要求的时刻,输出即可。

编写的函数如下。

int gcd(int a,int b)
{
    if (a%b==0) return b;
    else return  gcd(b,a%b) ;
}
int work2()
{
    int h,m,s,x,y,z;
    for (h=0;h<=6;h++)
        for (m=0;m<60;m++)
            for (s=0;s<60;s++)
            {
                x = 3600*h + 60*m + s ;  // 时针转的角度
                y = 720*m + 12*s ;       // 分针转的角度
                z = 720*s ;              // 秒针转的角度
                int hm=x>y?x-y:y-x;
                hm=hm%43200;
                if (hm>43200-hm)    // 通分后,圆盘一周360度变成 43200度(360*120)
                    hm=43200-hm;
                int k = gcd(hm,120) ;
                int hm1=hm/k;      // 时针与分针的夹角hm1/hm2
                int hm2=120/k;
                int ms=y>z?y-z:z-y;
                ms=ms%43200;
                if (ms>43200-ms)    // 通分后,圆盘一周360度变成 43200度(360*120)
                    ms=43200-ms;
                k = gcd(ms,120) ;
                int ms1=ms/k;      // 分针与秒针的夹角ms1/ms2
                int ms2=120/k;
                if (hm1!=0 && hm1*ms2==2*ms1*hm2)
                {
                    printf("%d %d %d\n",h,m,s);
                    return;
                }
            }
}

执行上面的处理函数,输出结果为:4 48 0

有了上面的处理结果,提交给本题的源程序如下。

#include <stdio.h>
int main()
{
    char T;
    scanf("%c",&T);
    if (T=='A') printf("379187662194355221\n");
    else if (T=='B') printf("4 48 0\n");
    return 0;
}