CSP-J 2022 入门级 第一轮 阅读程序(3) 第28-34题

【题目】

CSP-J 2022 入门级 第一轮 阅读程序(3) 第28-34题
阅读程序

01 #include <iostream>
02
03 using namespace std;
04
05 int n, k;
06
07 int solve1()
08 {
09     int l = 0, r = n;
10     while (l <= r) {
11         int mid = (l + r) / 2;
12         if (mid * mid <= n) l = mid + 1;
13         else r = mid - 1;
14     }
15     return l - 1;
16 }
17
18 double solve2(double x)
19 {
20     if (x == 0) return x;
21     for (int i = 0; i < k; i++)
22         x = (x + n / x) / 2;
23     return x;
24 }
25
26 int main()
27 {
28     cin >> n >> k;
29     double ans = solve2(solve1());
30     cout << ans << ' ' << (ans * ans == n) << endl;
31     return 0;
32 }

假设 int 为 32 位有符号整数类型,输入的 n 是不超过 47000 的自然数、 k 是不超过 int 表示范围的自然数,完成下面的判断题和单选题:
判断题
28. 该算法最准确的时间复杂度分析结果为 𝑂(log 𝑛 + 𝑘) 。( )
29. 当输入为“ 9801 1 ”时,输出的第一个数为“ 99 ”。( )
30. 对于任意输入的 n ,随着所输入 k 的增大,输出的第二个数会变成“ 1 ”。( )
31. 该程序有存在缺陷。当输入的 n 过大时,第 12 行的乘法有可能溢出,因此应当将mid 强制转换为 64 位整数再计算。( )
单选题
32. 当输入为“ 2 1 ”时,输出的第一个数最接近( )。
A. 1
B. 1.414
C. 1.5
D. 2
33. 当输入为“ 3 10 ”时,输出的第一个数最接近( )。
A. 1.7
B. 1.732
C. 1.75
D. 2
34. 当输入为“ 256 11 ”时,输出的第一个数( )。
A. 等于 16
B. 接近但小于 16
C. 接近但大于 16
D. 前三种情况都有可能

【题目考点】

1. 二分

【解题思路】

观察solve1函数,明显是二分答案算法。
满足mid*mid<=n时,l=mid+1取右半边。
最后取l-1,由于l都是mid+1,所以最后取到的是满足条件的mid。
可以看出,这个二份答案求的是:满足mid*mid<=n条件的,mid的最大值。
实际就是求 ⌊ n ⌋ \lfloor \sqrt{n} \rfloor n
至于solve2函数,传入的x是: ⌊ n ⌋ \lfloor \sqrt{n} \rfloor n ,而当 n \sqrt{n} n 不是整数时, n / x n/x n/x是个略大于 n \sqrt{n} n 的数字。 ⌊ n ⌋ \lfloor \sqrt{n} \rfloor n 与n/x二者取平均数后的值赋值给x,x变得更接近 n \sqrt{n} n
重复这一过程,会使x不断逼近 n \sqrt{n} n

28. 该算法最准确的时间复杂度分析结果为 O ( l o g n + k ) O(logn + k) O(logn+k) 。( )
答:正确。solve1函数是二分算法,二分查找的范围为n,复杂度为 O ( l o g n ) O(logn) O(logn),solve1求出值后,把值传给solve2函数。sovle2函数里面只有k次循环,复杂度为 O ( k ) O(k) O(k),所以整体复杂度为 O ( l o g n + k ) O(logn+k) O(logn+k)
29. 当输入为“ 9801 1 ”时,输出的第一个数为“ 99 ”。( )
答:正确。
sove1求出 ⌊ n ⌋ = ⌊ 9801 ⌋ = 99 \lfloor \sqrt{n}\rfloor=\lfloor \sqrt{9801}\rfloor=99 n =9801 =99
sove2中x=99,k为1,for循环执行一次,x=(x+n/x)/2=(99+9801/99)/2=99
输出ans为99。
30. 对于任意输入的 n ,随着所输入 k 的增大,输出的第二个数会变成“ 1 ”。( )
答:错误。
随着输入k的增大,输出的第二个数会接近或等于 n \sqrt{n} n
31. 该程序有存在缺陷。当输入的 n 过大时,第 12 行的乘法有可能溢出,因此应当将 mid 强制转换为 64 位整数再计算。( )
答:错误
题目限定了n最大是47000,第一次求出mid=n/2为23500,mid*mid为 2350 0 2 23500^2 235002=552250000,int类型可以表示该数字,并不会溢出。
(如果说n过大会超过题目限定的47000,那极端一点,当n特别大时,转为64位的long long类型计算仍然可能溢出。)
32. 当输入为“ 2 1 ”时,输出的第一个数最接近( )。
A. 1
B. 1.414
C. 1.5
D. 2

答:选C。
solve1传入2,求出结果为 ⌊ 2 ⌋ = 1 \lfloor \sqrt{2} \rfloor = 1 2 =1
把1传入solve2,x为1,循环1次,x = (x+n/x)/2=(1+2/1)/2=1.5,函数的返回值,也就是ans的值为1.5

33. 当输入为“ 3 10 ”时,输出的第一个数最接近( )。
A. 1.7
B. 1.732
C. 1.75
D. 2

答:选B。
solve1传入3,求出结果为 ⌊ 3 ⌋ = 1 \lfloor \sqrt{3} \rfloor = 1 3 =1
把1传入solve2,x为1,循环10次,,每次循环让x=(x+n/x)/2,用模拟运行法

kx
0(1+3/1)/2=2
1(2+3/2)/2=1.75
2(1.75+3/1.75)/2=1.732
3(1.732+3/1.732)/2=1.732

后面不用算了,我们通过分析程序已知x最终会不断接近 3 \sqrt{3} 3 的值,进行多次循环后,结果的前几位一定是1.732,不会改变。

34. 当输入为“ 256 11 ”时,输出的第一个数( )。
A. 等于 16
B. 接近但小于 16
C. 接近但大于 16
D. 前三种情况都有可能

答:选A。
solve1的结果为 ⌊ 256 ⌋ = 16 \lfloor \sqrt{256} \rfloor=16 256 =16,已知 256 = 16 \sqrt{256}=16 256 =16,所以在solve2中x=(x+n/x)/2=(16+256/16)/2=16,每次计算后x的值不变,都是16。因此最后输出的值等于16。

【答案】

  1. 正确
  2. 正确
  3. 错误
  4. 错误
  5. C
  6. B
  7. A
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值