第一次机考题目回顾

第一次机考的几道题目颇值得探索

题目2385 0请高明

https://acm.sjtu.edu.cn/OnlineJudge/problem/2385
https://acm.sjtu.edu.cn/OnlineJudge/problem/2385

涉及算法

1、深搜
2、判断字符的相同

两次WA的原因

在判断两个字符串的函数中加入了 a== b 返回-1
使得一个字符串无法自己连接自己

int cmp(string a,string b)
{
    if(a == b)
    {

        return -1;
        // a is the small b is the big
    }

   ...
}

解题思路

1、接收字符串,对每一个字符串进行遍历,计算将 j 连接到 i 的末尾的重合数,然后存在数组map[i][j]之中
2、设定一个数组visit[n],用来存储字符串使用过的次数,从2减少,当为0的时候无法继续使用。
3、进行深搜,对于每一个字符串,寻找使用次数大于0的字符串,如果这两个字符串之间有重叠部分,进行搜索,并把这个字符串使用次数减一,记得在后面加上状态恢复。
4、若在进入一次函数后,搜索的过程中没有执行过一次下一级调用,说明当前搜索到达了末尾,存储max = (max,l)
5、最后输出max

题目 2423

https://acm.sjtu.edu.cn/OnlineJudge/problem/2423

这道题一直卡的错误就是取模取少了
首先先明晰什么时候同模
乘法 加法 减法同模 所以我们在写的过程中使用很多乘法。
但是对于这样一个式子

ans = (ans + a * xx  *  cal(y, k) ) %  p;

感觉上并没有任何问题,但实际上在计算的过程中 a * xx本身就有可能接近溢出的边界了,为了防止溢出,需要对每一次乘法进行取模 ,只有这样才能解决这个题目。

ans = (ans + (a * xx)%p  * cal(y, k)%p) % p;

而这道题后面有两个点会超时,是因为这道题在计算多项式的过程中我们使用了多次快速幂,这会使得时间复杂度较高,而我们注意到,求幂的操作可以成为下一次操作的基数,可以进行递归调用,而这样会有两个返回值,对于有两个返回值的情况我们可以使用pair<>来作为返回值
这道题没完成的部分:
1、求幂的优化
2、对于K 很小的时候采用一般策略
3、当K为偶数的时候如何进行式子的拆分

再附上一部分学长的题解:

2423

首先,很重要的一点,这道题目的数据范围是\(10^{16}\),因此必须使用long long,否则必定会炸。

主要的考察点在于如何快速地计算\(y^0+y^1+...+y^k\)这么一个多项式,我们将它记为\(f(y,k)\)。大家第一时间想到的可能就是等比数列的求和公式,但是求和公式中有除法存在,在模p意义下的除法不能使用普通的除法,否则得到的结果是错误的。并且题目中不保证p是素数,因此不能用乘法逆元来解这道题,需要使用另一种方法。

对于这个问题,可以考虑递归求解。分3种情况讨论。当k较小的时候,可以直接计算出结果,这一点没什么好说的。当k较大的时候,如果k为奇数,那么\(y^0+y^1+...+y^k=(y^0+y^1+...+y^{\frac{k-1}{2}})\times (1+y^{\frac{k+1}{2}})\),因此\(f(y,k)=f(y,\frac{k-1}{2})\times (1+y^{\frac{k+1}{2}})\),可以递归地计算多项式的值。当y为偶数的时候也可以使用同样的方法,只是得到的式子稍微有一些不一样,可以自己尝试构造。

如果你按照以上方式写出一个递归的函数,那么提交之后大概率会得80分,这是因为每次递归调用函数的时候都需要调用一次快速幂计算\((1+y^{\frac{k+1}{2}})\)这一项(当k为偶数时可能有些不同,但是大体一样),而快速幂的时间复杂度是\(O(\log N)\),因此上述递归函数的时间复杂度是\(O(\log^2 N)\),根据刻意的设计会t两个点。可以将快速幂优化掉,将总体复杂度降为\(O(\log N)\)。可以将函数的返回类型设置为std::pair<long long, long long>,两个值中一个是模p意义下的和,另一个就是\(y^{\frac{k+1}{2}}\)的值。当k较小时,\(y^{\frac{k+1}{2}}\)可以直接计算。而当k较大时,可以通过递归调用得到的返回值计算当前所需的\(y^i\)的值,这个过程是\(O(1)\)的,因此就可以将时间复杂度优化至\(O(\log N)\)

剩下的内容就没什么花样了,每次输入都把结果加上当前计算得到的项,最后输出结果就可以。但是每一次进行运算操作的时候都要记得模p,否则可能会数据溢出。

posted @ 2024-10-17 20:37  FFEE  阅读(3)  评论(0编辑  收藏  举报