解题思路

根据题目描述和示例,我们可以发现以下规律:

  1. 初始时刻t=1,显示值为3
  2. 每个时刻的值会减1,直到减为1
  3. 按下按钮后,计数器会重置为上一个周期初始值的两倍

解题思路:

  1. 使用两个变量:
    • a:记录当前时刻
    • b:记录当前周期的初始值
  2. 先快速定位到目标时刻所在的周期
  3. 然后在周期内逐步调整到目标时刻

代码

#include <iostream>
using namespace std;

int main() {
    long long a = 1, b = 3;  // 初始状态
    long long target;
    
    cin >> target;
    
    // 定位到目标时刻所在的周期
    while (a < target) {
        a += b;      // 下一个周期的起始时刻
        b *= 2;      // 下一个周期的初始值
    }
    
    // 如果刚好是周期起始点
    if (a == target) {
        cout << b << endl;
    }
    // 否则在周期内调整
    else {
        cout << (a - target) << endl;
    }
    
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long a = 1, b = 3;  // 初始状态
        long target = sc.nextLong();
        
        // 定位到目标时刻所在的周期
        while (a < target) {
            a += b;      // 下一个周期的起始时刻
            b *= 2;      // 下一个周期的初始值
        }
        
        // 如果刚好是周期起始点
        if (a == target) {
            System.out.println(b);
        }
        // 否则在周期内调整
        else {
            System.out.println((a - target));
        }
    }
}
# 读取目标时刻
target = int(input())

# 初始状态
a, b = 1, 3

# 定位到目标时刻所在的周期
while a < target:
    a += b      # 下一个周期的起始时刻
    b *= 2      # 下一个周期的初始值

# 输出结果
if a == target:
    print(b)
else:
    print((a - target))

算法及复杂度

  • 算法:模拟 + 数学
  • 时间复杂度: - 为目标时刻,每次循环 翻倍,所以循环次数是对数级
  • 空间复杂度: - 只使用了常数个变量