ZOJ_Function 3061

来源:互联网 发布:java中io流的面试题 编辑:程序博客网 时间:2024/05/16 11:24

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;}


原创粉丝点击