Loading

CSP-J 2022

CSP-J 2022 总结

T1 乘方

思路

首先,不看数据范围,可以知道最简单的方法就是从 \(1\)\(b\) 循环一遍,求出 \(a ^ b\)

但是,现在有一个问题,\(b\) 太大了!

那该怎么办呢?

如果你仔细观察的话,就会发现题目有一个条件:如果大于 \(10 ^ 9\) 就输出 -1。

这说明了什么?

你知道 \(2 ^ {31} = 2147483648\),是 \(\ge 10 ^ 9\) 的,而你又知道对于同一个数,它 \(\log_2\) 得到的结果肯定要大于 它 \(\log_x\) \((x > 2)\) 的,那么如果加上判断是否大于 \(10 ^ 9\) 这个条件的话,循环最多执行 \(31\) 次。

但是,这里还要考虑一个事情,如果 \(a = 1, b = 10 ^ 9\) 呢?\(1\) 的任何次方都是 \(1\),还是会执行 \(10 ^ 9\) 次,所以需要特殊判断一下这种情况。

T2 解密

思路

70 分

首先,题目很明显告诉了我们一个公式:\(n = p \times q\),这就说明,\(p\)\(q\) 都得是 \(n\) 的因数,那么可以直接找约数,再判断是否满足条件。这样,你就拿到了宝贵的 60 分。

如果你是个爱仔细观察数据的同学,你就会发现,第 7 个数据点保证 \(q = p\),直接特殊判断即可。

100 分

如果仔细观察数据范围的话,你会看到题目给了一个貌似没有什么用的 \(m\)\(m = n - e \times d + 2\)

那么,就可以考虑从 \(m\) 下手。

首先,我们知道 \(e \times d = (p - 1) \times (q - 1) + 1\),化简后也就是 \(e \times d = pq - p - q + 1 + 1\)

那么 \(m = n - e \times d + 2 = n - (pq - p - q + 1 + 1) + 2 = n - pq + p + q - 2 + 2\)

\(n = p \times q\),所以 \(m = n - pq + p + q - 2 + 2 = p + q\)

紧接着,我们应该都知道 “和一定,差小积大”,也就是当和是一个定值的时候,两个数的差越小,乘积就越大。

而在这里,你又知道 \(m\) 就是 \(p\)\(q\) 的和,而乘积会随着它们的差变小而越变越大,所以,你会神奇的发现,这道题有单调性!!!

那么,就可以请二分登场了。

这个事情就变得很简单了,二分 \(p\),判断乘积是大于 \(n\) 还是小于 \(n\),最后判断并输出即可。

其实还有一种解方程的解法,只是我不会。

T3 逻辑表达式

思路

首先,我们得知道,逻辑表达式实际上只有 2 种运算符 (&, |),但是因为 () 的加入,使得这个运算变得更加复杂了。

所以,题目温馨的给出了没有 () 的数据,我们就先处理这种情况。

首先,我们知道 & 的运算优先级是大于 | 的,所以其实可以简单的将 | 看作 +& 看作 *,这就对应到了洛谷上的另一道题,P1981。

其实就是用栈来模拟,当碰到 & 时,就运行栈顶的所有 | 运算符。

那么,() 到底会影响到什么呢?

我们都知道,在 () 内的所有运算,都是优先于 () 外的运算的,所以,() 影响的其实是 优先级

那么我们就可以将 & 的优先级定为 1,| 的优先级定为 0。

而这里,有两种优先级,所以我们可以在每一层括号中,将所有运算符的优先级都加上 2,当脱离出这一层括号时,就减少 2。

所以可以用一个基础值来记录经过了多少个括号,然后对于每一个运算符,直接用基础值加上原本的运算符优先级就可以了。

那么短路次数又应该怎么计算呢?

其实也很简单,只要在每次运算的时候进行计算就可以了。

如果当前不发生短路,就直接将两个运算数带着的短路次数进行相加即可,否则,就只留下前面运算数的短路次数,并且加上这次短路即可。

posted @ 2023-03-02 22:46  chengning0909  阅读(1)  评论(0编辑  收藏  举报