一道算法题:
原题地址
Bob has a strange counter. At the first second,t=1 , it displays the number 3. At each subsequent second, the number displayed by the counter decrements by 1.
The counter counts down in cycles. In the second after the counter counts down to 1, the number becomes 2X the initial number for that countdown cycle and then continues counting down from the new initial number in a new cycle. The diagram below shows the counter values for each time t in the first three cycles:
- 下面的代码结果正确,却是最笨的方法,所以时间上出现了超时,没有得到满分。
c语言代码
int main(){
int t;
int sum = 3;
int j = 2;
cin >> t;
int bottom = 0;
for( int i = 1 ; ; i++ ) {
if( t <= sum ) {
bottom = sum;
break;
}
sum += j * 3;
j *= 2;
}
cout<<bottom-t+1;
return 0;
}
但是看过大神的讲解后,自己推倒了一遍公式总算写出来了
function main(t) {
var t = parseInt(readLine());
var n = Math.floor(Math.log((t-1)/3+1)/Math.log(2));
var topValue = 3 * Math.pow(2,n);
var topTime = topValue - 2;
var value = topValue - ( t - topTime );
console.log(value);
}
这道题的关键代码就是
var n = Math.floor(Math.log((t-1)/3+1)/Math.log(2));
因为Math.log()是以e为底的对数公式,所以要进行公式变化。
其中n代表所在列的index,从零开始。
我们可以利用等比序列的求和公式得出每一列的第一个time的值是
3*(2^n-1)+1 (n从零开始。)
我们假设 time t 在列 n 中。
3*(2^n)+1 = t;
log2((t-1)/3+1) = n
n向下取整,就是当前所在列的index