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