ZOJ_Function 3061

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3061

题意:

定义f(i)为i表示成3进制之后,从最高位开始找到的第一个2前面的数,如 142 =

 (12021)3, f(142) = (1)3 = 1.如果没有这样2则 f(i) = i。求f(1) + f(2) + f(n) 的值。 

思路:

因为n的值<=1e9,直接求的话肯定会超时,这样我们就要删除掉一部分的数不去直

接求,而通过其他的某些数来得到答案,由题意可以发现,我们关心的只是最高位

的2的位置,只要最高位的2的位置确定,无论地位怎么变都不会影响结果,比如

f( 1121010 ) = f( 1120101 ) = f( 1120000 ),我们有这个优化就可以过这题了。

代码:

#include<stdio.h>
#include<string.h>
int N , K ;
void solve(){
    int res = 0 , mid , n = N , mm;

    while(n >= 1){
        int pos = -1 ;
        int cc = 0 ;
        for(int temp=n ;temp;){
            if(temp%3 == 2){
                pos = cc ;
                mm = temp ;
                mid = temp / 3 ;
            }
            cc ++ ;
            temp /= 3 ;
        }
        if(pos == -1){
            res = (res + n) % K ;
            n-- ; continue ;
        }
        for(int c=0;c<pos;c++)
            mm = mm * 3 ;
        res = ( res + mid*((n-mm+1)%K)%K ) % K ;
        n = mm - 1 ;
    }
    printf("%d\n",res);
}
int main(){
    while(scanf("%d %d",&N,&K) == 2){
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值