1 条题解

  • 0
    @ 2025-4-9 13:20:31

    题目分析

    题目模拟了一个驾照扣分(demerit)和奖励分(merit)系统,要求根据司机的违规记录计算并输出其分数变化情况。主要规则包括:

    1. 初始状态:新司机无扣分也无奖励分。
    2. 违规扣分:每次违规扣 221515 分。
    3. 奖励分获取:连续两年无违规且无扣分时,获得 11 奖励分(上限 55 分)。
    4. 扣分抵消:每个奖励分可抵消 22 扣分。
    5. 年度减免:每年无违规时,扣分减少 $\max\left(\left\lfloor \frac{\text{扣分}}{2} \right\rfloor, 2\right)$。
    6. 输出触发:每次分数变化时输出当前状态。

    核心函数

    1. facs(n)
      • 功能:将日期 yyyymmdd 分解为 yearmonthday

    主逻辑

    1. 初始状态输出

      • 驾照颁发日直接输出无扣分/奖励分。
    2. 处理违规记录

      • 年度扣分减免:从上次违规日期到当前违规日期,每年减少扣分:
      • 奖励分累积:若连续两年无扣分,每两年增加 11 奖励分:
    3. 新违规处理

      • 若存在奖励分,优先抵消扣分:
      • 输出当前分数状态。
    4. 后续处理

      • 扣分清零后累积奖励分:每年无违规时,每两年增加 11 奖励分,直到满 55 分:
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<string>
    using namespace std;
    int year,month,day,mer,demer;
    void facs(int n)
    {
     year=n/10000;//计算年份月份日子
     n%=10000;
     month=n/100;
     day=n%100;
    }
    int main()
    {
      int n,m,k;
      scanf("%d",&n);
      k=n;
      facs(k);
       printf("%04d-%02d-%02d No merit or demerit points.\n",year,month,day);//先输出最开始的
      while(~scanf("%d%d",&n,&m))
      {
          int count1=0;
          for(k+=10000;k<=n;k+=10000)//从K日期开始到n结束
          {
              if(demer>0)
              {
                  demer-=max(2,int(demer+1)/2);//
                  facs(k);
                  if (demer>0) printf("%04d-%02d-%02d %d demerit point(s).\n",year,month,day,demer);
                  else
                  {
                      demer=0;
                      printf("%04d-%02d-%02d No merit or demerit points.\n",year,month,day);
                  }
              }
              else
              {
                  if (count1%2!=0)//count1从0开始,变成1的时候代表已经第二年是demerit为0了
                  {
                      mer++;
                      facs(k);
                      printf("%04d-%02d-%02d %d merit point(s).\n",year,month,day,mer);
                  }
                  count1++;
              }
          }
              k=n;
              demer+=m;
              facs(k);
              if (mer)//如果merit不为零就可以抵消demerit
             {
              while (demer>0 && mer>0)
                  mer--,demer-=2;//并且要清空merit为0
              mer=0;
             }
          if (mer>0)
              printf("%04d-%02d-%02d %d merit point(s).\n",year,month,day,mer);
          if (demer>0)
              printf("%04d-%02d-%02d %d demerit point(s).\n",year,month,day,demer);
          if (demer==0 && mer==0)
              printf("%04d-%02d-%02d No merit or demerit points.\n",year,month,day);
      }
      while (demer!=0)
      {
          k+=10000;
          facs(k);
          demer-=max(2,(int)((demer+1)/2));
          if (demer>0) printf("%04d-%02d-%02d %d demerit point(s).\n",year,month,day,demer);
          else
          {
              demer=0;
              printf("%04d-%02d-%02d No merit or demerit points.\n",year,month,day);
          }
      }
      for (mer=0;mer<6;mer++)//从0开始
      if (mer)
      {
          k+=20000;
          facs(k);
          printf("%04d-%02d-%02d %d merit point(s).\n",year,month,day,mer);
      }
      return 0;
      }
    
    • 1

    信息

    ID
    1564
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者