[NICA #1] 弹幕题解
本来想用这题写整活题解的。
整活题解
看到这题我们可以通过循环枚举检查某处能否成为安全点,只要找到即为答案,但是如果我们考虑最坏的情况,我们枚举到的每一个点都在弹道上,那么我们就要一直枚举,直到
事实上只要数据巧妙无论你是正序、倒序、枚举奇数、枚举偶数、枚举质数都可以出现最坏的情况(如果出题人足够狡猾)!
我们可以换个思路,我们可以随机一个点检查!随机到每一个点的概率相等,通过数据范围可以发现对于每个点成功的概率极高!而随机让出题人无法预判你每个输出的数,轻轻松松就能通过!
关于为什么要用随机化思想(对重要结论的证明),举个例子:
有五十张卡片,你最多选三张,而有四张是红色的,其余是白色的,你希望得到白卡,你不知道某一张是红的或白的,也许你想到了一种选卡方式,比如选出第一张、第五张、第十四张,但是给你卡的人非常智慧,他预想到了你会使用一种定式获取卡片,于是提前在你想的三个地方放上了红卡,甚至让你多次重复这一操作,每一次的位置都不一样,这样无论如何都你选的位置都会出现三张红卡!
但你可以使用抛骰子的方式来决定你的选择,摆卡片的人并不能预判你的(骰子的)选择,事实上,他的摆法对你没什么影响,因为无论放在什么位置你取到红卡片的概率一致!此时只要你不是太非酋就能选出至少一张白卡片了。
注意:
-
一定要将当前时间作为随机种子,否则无法保证通过每个阴间测试点(似乎暂时没卡,但不代表以后的随机化题目不会卡)
-
记得取模!
代码:
#include <bits/stdc++.h>
using namespace std;
long long n;
long long o;
long long a[200010],b[200010],c[200010];
bool check(long long x){ //检查位置
for(int i=1;i<=n;i++){
if(x*x*x+a[i]*x*x+b[i]*x+c[i]==0){
return 0;
}
}
return 1;
}
int main(){
srand(time(NULL)); //用时间当随机数种子
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i]>>c[i];
}
while(1){
o=rand()%1000001; //取模,否则会超出输出范围限制
if(check(o)){
cout<<o; //发现可行位置
return 0;
}
}
return 0;
}