ac.nowcoder
题目
- 题目描述:立华奏在学习初中数学的时候遇到了这样一道大水题: “设箱子内有 n 个球,其中给 m 个球打上标记,设一次摸球摸到每一个球的概率均等,求一次摸球摸到打标记的球的概率” “emmm…语言入门题” 但是她改了一下询问方式:设最终的答案为 p ,请输出 p 小数点后 K1 到 K2 位的所有数字(若不足则用 0 补齐)
- 输入描述:第一行一个整数 T,表示有 T 组数据。接下来每行包含四个整数 m,n,K1,K2,意义如「题目描述」所示。
- 1≤m≤n≤10的9次方,1≤K1≤K2≤10的9次方、0≤K2−K1≤10的5次方,T≤20。
- 输出描述:输出 T 行,每行输出 K2−K1+1个数,表示答案。注意同行的数字中间不需要用空格隔开。
解答
- 不用从头开始模拟,只需要从 K1 位开始模拟就可以了。 直接通过快速幂+取模算出第 K1位的数字。然后我们发现 K2−K1≤10的5次方,所以暴力枚举除法过程就可以。 时间复杂度 O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
inline LL qpow(LL a,LL b,LL p){
LL res = 1;
for(;b;b>>=1,a=a*a%p)
if(b&1) res = res * a % p;
return res;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
LL a,b,k1,k2;
std::cin >> a >> b >> k1 >> k2;
LL ans = ((a % b) % b * qpow(10, k1 - 1, b)) % b;
for(LL i = k1;i <= k2;i++,ans = ans % b) {
ans *= 10;
std::cout << ans / b;
}
std::cout << std::endl;
}
return 0;
}