“安全赛,出题的方式很新颖,感一共8题感觉花不了多少时间,下下来玩玩看
无聊刷知乎的时候看到了这个挑战赛,出题方式很新颖。我不甘寂寞又下下来看看到底是什么套路。据说这个是腾讯安全的技术牛人送给一岁儿子的礼物,题目内容寓意为陪伴孩子成长,题目范围涵盖从小学,中学,大学和工作。内容以算法和安全为主。赛题地址/参赛方式如链接所示。答题环境的方式也很有趣,这里略过~
前三题是小初中数学题,直接略过,从第四题开始记录。
第四题
题目:求解 1234567^12345678901234567890)%999999997
受到前三题的影响,我以为这个也能通过手算或者题目特殊的规律完成(非计算机科班和非竞赛党的痛),试了半天后发现无果。于是开始网上搜索大数取模,出现最多的是RSA加密算法中的核心算法——蒙哥马利算法(快速幂取模算法)。搜索结果里还有基于欧拉函数(费马小定理)的大数取模算法,但我看了看999999997不是质数所以不能使用这个算法?(不确定)。总之,就直接采用快速幂取模算法来试试,就成功啦。
快速幂取模算法的核心思想是基于以下定理:
公式:(a*b)mod c=[(a mod c) * (b mod c)] mod c;
公式: a^b mod c =(a mod c)^b mod c;
因此该算法的核心代码如下所示,详细介绍可以参考链接:
1
2
3
4
5
6
7
8
9
10
11
long long Montgomery()
{
long long int res = 1;
while (exp_1)
{
if (exp_1 & 1)//如果为奇数
res = (res * base) % mod;
exp_1 >>= 1;//指数对半
base = (base * base) % mod;//底数平方
}
return res;
值得注意的是这里指数为12345678901234567890,已经超过了long long类型所能表示的最大值,这是一个坑点。由于这个值的溢出,让我花了一些时间调试。后来把数的类型换为unsigned long long后解决,如果值更大的话,似乎需要通过设置成string类型来解决?暂时先这样吧,接着看下面的问题~
第五题
题目:1_2_3_4_5_6_7_8_9=-497,每处_填入1个运算符+-*/,且4个运算符必须都用上,使得等式成立(答案保证唯一),求出相应的表达式?
这题乍一看似乎思路很简单,每个空格只有四种可能性,那么一共8个空格的话总共的可能性也就4^8种,所以写个程序遍历并找到对应的结果即可?但出题人是否有更简洁或巧妙的思路呢?不得而知,我就用暴力搜索的方法得出了结果。
由于篇幅原因不再粘贴代码,网上有现成的(参考链接),将判定的值修改,并找到均适用加减乘除的项即可。
第六题
x^5-2x^4+3x^3-4x^2-5x-6=0, x(精确到小数点后14位)=
求解一元五次方程,比较简单,印象是研究生的时候学过的数值分析的课程,用迭代的方式求解,如二分法牛顿法,当时考试的时候是通过手按计算器求解结果的,倒没用程序实现过,这回用牛顿法实现了一下,随意写了个迭代10w次,就通过了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
double calcu_fx(double x) {
return pow(x, 5) - 2 * pow(x, 4) + 3 * pow(x, 3) - 4 * pow(x, 2) - 5 * x - 6;
}
double calcu_fxp(double x) {
return 5 * pow(x, 4) - 8 * pow(x, 3) + 9 * pow(x, 2) - 8 * x - 5;
}
int main()
{
int iter = 0;
double res;
double x = 3.4131;
while (iter < 100000) {
x = x - calcu_fx(x) / calcu_fxp(x);
iter++;
}
res = x;
printf("%.14lf",res);
return 0;
}
第七题
请输入8位数字PIN码:
题目不知道是什么含义了,咋整?
想了很久不知道从哪里入手。。知道的套路太少了。还是等等后续大佬们给出结果吧。已关注腾讯安全公众号,期待最后给出的结果,安全小白也可以学习学习,到时候再补充记录吧。T T
后续整体答案解答:https://mp.weixin.qq.com/s/IrX0NagbcmHqACcjW62yFQ。