CodeForces 471C 规律题

             好吧,在比赛的时候在做471D,鼓捣了半天没弄出来。。。最后比完赛发现是471D的KMP在写的时候一个小细节没注意。。。。嘛,不过这道题目我也是想了一会儿的,首先我觉得这个应该是找规律的一道题目吧。

           好吧,首先想摆到某一层之后卡片数有什么特点,设摆到了第L层,此时有K个小屋(也就是“∧”型),我们可以通过这两个假设把总卡片数推出来,那么,总的卡片数应该就是3*K  - L,因为本来有K个小屋,每个小屋上有一个天花板,应该是3K,但是每一层最左边(或者最右边)的小屋是没有天花板的,因此每一层就要减1。

          那么,我们此时就得到了判定在某一数量的卡片n下,能否摆在第L层的的一个判定公式,假若n+L能够被3整除,那么n就可以摆L层(但是不一定能够摆在L-1层)。有了这个之后,只需要把最大的层数求出来,然后对每一层进行枚举即可。

         求最大层数L,我们就需要知道在层数为L的情况下最少能够摆多少张卡片。我们可以发现,第一次需要1个小屋,第二层需要3个,第三层需要6个,。。。很轻易的推导出需要小屋数量的通项公式是(L + 1)*L / 2,既然最少需要这么多小屋,而且总的卡片数满足n + L % 3 == 0,我们带到我们的式子里面去,又是一个关系。 3*(L + 1)* L /2   - L<= n。这个就是n满足的一个关系式, n要大于等于其最大层数的最少卡片数。然后我们把L解出来,向下取整,便是最大层数,然后枚举即可,枚举的代码我写在注释里面了,我真正的代码不是这么写的。。。

          Tips:judge把n的每一位加起来,用于判断能否被3整除,因此,最终变成了判定区间【judge +1,judge+high】内有多少个数能够被3整除



#include<cstdio>
#include<cmath>

using namespace std;

long long n,ans,high,judge;
char str[15];

int main(){
    scanf("%lld",&n);
    high=floor((-1.0+pow(1+24*n,0.5))/6);
    sprintf(str,"%lld",n);
    for(int i=0;str[i];++i)
        judge+=str[i]-'0';
    printf("%lld\n",(judge+high)/3-judge/3);
//    for(int times=1;times<=high;++times){
//        ++judge;
//        if(judge%3==0)
//            ++ans;
//    }
//    printf("%lld\n",ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值