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