解题思路
根据题目描述和示例,我们可以发现以下规律:
- 初始时刻t=1,显示值为3
- 每个时刻的值会减1,直到减为1
- 按下按钮后,计数器会重置为上一个周期初始值的两倍
解题思路:
- 使用两个变量:
- a:记录当前时刻
- b:记录当前周期的初始值
- 先快速定位到目标时刻所在的周期
- 然后在周期内逐步调整到目标时刻
代码
#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))
算法及复杂度
- 算法:模拟 + 数学
- 时间复杂度:
-
为目标时刻,每次循环
翻倍,所以循环次数是对数级
- 空间复杂度:
- 只使用了常数个变量