CodeForces 337C SDUT秋季训练--周赛(10.31)

我要哭了!!!别劝我!!!我真的哭了!!!

真是醉了;

题意:n次答题,答对一个问题加一分,连击算一次,如果连击到K的话,总分double;如果出现答错的情况,连击清零,总分不变;小明答对了m道题,问最小的分数是多少;

思路:贪心啊,绝壁是贪心啊;想让他分数最小,要避免让他连击满K,避免出现double的情况;如果还是有连击,就要让连击在前面,尽量避免在后面;

比赛的时候完全SB了,应该努力的推公式啊尼玛!!

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define mod 1000000009
long long pow(long long a,long long b)//快速幂
{
    long long sum=1;
    while(b)
    {
        if(b%2==1)
        {
            sum*=a;
            sum%=mod;
        }
        a=a*a%mod;
        b/=2;
    }
    return sum;
}
int main()
{
    long long  n,m,k,s;
    while(~scanf("%lld%lld%lld",&n,&m,&k))
    {
        long long ans=n-m;//错的题数
        long long k1=n/k;//如果完全避免连击需要的题数;
        if(ans>=k1)//判断,错的题数大于等于完全避免连击的题数的话,就说明不可能出现连击;所以最后得到的分数一定是正确的题数;
        {
            printf("%lld
",m);
        }
        else//如果一定会有连击的情况,处理;方法写搓了;最后的分数应该是连击的分数加上正确的正确的分数加上连击的分数;
        {
            long long cnt=n-ans*k;
            long long kk1=cnt/k;
            long long kk2=cnt%k;
            s=0;
            s=pow(2,kk1);//快速幂;注意取模
            s=(1-(s%mod))%mod;
            s=-(2*(s%mod))%mod;
            s=((s%mod)*(k%mod))%mod;
            s=s+kk2;
            long long k1=(ans*(k-1)%mod)%mod;
            s=(s+k1+mod)%mod;
            printf("%lld
",s);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/qioalu/p/4926338.html