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

· · 题解

//P1664 每日打卡心情好
//模拟样例后,对活跃值奖励作如下解释:
//第几天    该天获得活跃值奖励 
//1<=T<=2       1
//3<=T<=6       2
//7<=T<=29      3
//30<=T<=119    4
//120<=T<=364   5
//365<=T        6
//9-12天理解,建议拿出纸笔进行计算
//第9天:1//我回来了,可惜连续天数变成5-4=1天了TQT……获得1点经验,共9点,连续2天
//连续天数 5-2^(3-1)+1=2 +1指的是第9天这天 
//第10天:0//啊,事情太多给忘了
//第11天:1//连续天数变成2-1=1天。获得1点经验,共10点,连续2天。
//连续天数 2-2^(1-1)+1=2 +1指的是第11天这天 
//第12天:1//获得2点经验,共12点,连续3天。
//连续天数 2+1=3 +1指的是第12天这天。
//得到上述结论,样例大约模拟了3次。 
//样例通过后,提交,测试点4,5 WA 
//看了讨论,https://www.luogu.org/discuss/show?postid=4548摘抄如下:
//一定不要忽略当连续天数被扣到0以下的情况,确实没考虑到此种情况,马上修改,提交AC 2017-10-1 14:27
//不看谈论,要想到"一定不要忽略当连续天数被扣到0以下的情况"上述问题,估计是很难很难。 
#include <stdio.h>
int mypow(int a){//自己编的幂次方的函数,针对该题特有的函数 
    int ans=1,i;
    for(i=1;i<=a-1;i++)
        ans*=2;
    return ans;
}
int main(){
    int n,i,b,T=0,ans=0,count=0;//count 连续0天统计  T指的是当前连续天数
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&b);
        if(b){//b==1
            if(count){//有连续0天 天数
                T-=mypow(count);
                if(T<0)//1 //一定不要忽略当连续天数被扣到0以下的情况,确实没考虑到此种情况,漏了改功能,现添加上 
                    T=0;
                count=0; 
            }
            T++;
            if(1<=T&&T<=2)ans+=1;
            else if(3<=T&&T<=6)ans+=2;
            else if(7<=T&&T<=29)ans+=3;
            else if(30<=T&&T<=119)ans+=4;
            else if(120<=T&&T<=364)ans+=5;
            else if(365<=T)ans+=6;
        }else{//b==0
            count++;
        }
    }
    printf("%d\n",ans);
    return 0;
}