题解 P1664 【每日打卡心情好】

· · 题解

一道很棒的模拟题。

具体思路如下面几步:

①判断有没有打卡;

如果打卡,加上对应的经验值,并将未打卡的惩罚措施还原成初始化(注意这一点很重要,坑了作者好久QAQ)

如果未打卡,扣除相应的连续打卡天数…………

咚咚咚!重点来啦!偶的扣除方法与楼上那几位dalao不太一样…………

扣除方法可以这样理解:
第一天扣除1;
后面每一天的扣除天数都是2^(n-2)

这样就OK啦~

②判断连续天数是不是在合法范围内(>=0

这个比较简单,不过还是很坑啊2333

对于连续天数<0,将连续天数改成0;
对于连续天数>=0,什么也不要干......

③提交!

④AC!

#include <bits/stdc++.h>//万能头文件
using namespace std;
int n;//天数
int ans;//用来存储积分
int lx;//连续天数
int yl=1;//遗漏天数
bool flag=true;//这里是判断惩罚时的标记变量(是第一次惩罚1还是第二次惩罚1)
int main()
{
    cin>>n;//输入
    int x;
    for(int i=1;i<=n;i++)
    {
        cin>>x;//输入
        if(x==1)//打卡了
        {
            lx++;//连续天数+1
            if(lx>=1)
                ans++;
            if(lx>=3)
                ans++;
            if(lx>=7)
                ans++;
            if(lx>=30)
                ans++;
            if(lx>=120)
                ans++;
            if(lx>=365)
                ans++;//判断能获得多少积分
            yl=1;
            flag=true;//惩罚机制初始化
        }
        else//没打卡
        {
            lx-=yl;//连续天数-
            if(yl==1&&flag) yl=1,flag=false;//判断,如果是第一次惩罚1天,那么第二次还是惩罚1天,标记变量更新
            else yl*=2; //对于其它的直接*2
        }
        if(lx<0)
            lx=0;//第二点所说的,判断连续天数是不是在合法区间内
    }
    cout<<ans<<endl;//输出
    return 0;
}

总体而言,还是不难。。。

不过这道题可能要成为历史了。。。