「国家集训队」单选错位 题解
本文网址:https://www.cnblogs.com/zsc985246/p/16366596.html ,转载请注明出处。
题目大意
试卷上共有 $ n $ 道单选题,第 $ i $ 道题有 $ a_i $ 个选项,每个选项成为正确答案的概率都是相等的。
$ A $ 全部做对,但抄错位了:每题都向后抄了一个位置,特别地,第 $ n $ 道题目抄到了第 $ 1 $ 道题目的位置。
$ A $ 想知道自己期望能做对几道题目。
思路
数据范围 $ n \le 10^7 $ ,说明需要 $ O(n) $ 的算法解决。
通过样例仔细观察后,我们可以发现,第 $ i $ 题是否正确,只与第 $ i-1 $ 题的答案是否跟第 $ i $ 题相同有关。
举个例子:
$ a={2,3,1} $
对于第 $ 1 $ 题和第 $ 2 $ 题,正确答案的总情况数为 $ a[1] \times a[2] = 6 $ ,而两道题答案相同的只有 $ min(a[1],a[2]) = 2 $ 种。最终做对的概率为 $ \frac{min(a[1],a[2])}{a[1] \times a[2]} = \frac{1}{3} $ 。
为什么要求最小值?
因为当第二题答案为 3 时,第一题答案不可能与它相同。所以相同情况数取决于它们的最小值。
由上可得:两道题的正确答案情况总数为 $ a[i] \times a[i-1] $ ,两道题答案相等的情况有 $ min(a[i],a[i-1]) $ 种,所以答案需要加上一个 $ \frac{min(a[i],a[i-1])}{a[i] \times a[i-1]} $ 。
化简一下:
$ \ \ \ \ \ \frac{min(a[i],a[i-1])}{a[i] \times a[i-1]} $
$ = \frac{1}{max(a[i],a[i-1])} $
注意,这里的 $ min $ 变成了 $ max $ 。
当 $ min(a[i],a[i-1]) = a[i] $ 时,原式变为 $ \frac{1}{a[i-1]} $ ;
当 $ min(a[i],a[i-1]) = a[i-1] $ 时,原式变为 $ \frac{1}{a[i]} $ 。
综合一下,就是 $ \frac{1}{max(a[i],a[i-1])} $ 。
对于特殊情况只需要再加上 $ \frac{1}{max(a[n],a[1])} $ 即可。
最终公式为:
$ ans = \frac{1}{max(a[n],a[1])} + \underset{i = 2}{\overset{n}{\sum}} \frac{1}{max(a[i],a[i-1])} $
因此,代码出。
代码实现
#include<bits/stdc++.h>
#define ll int
const ll N=10000010;//1e7+10
using namespace std;
ll n,A,B,C,a[N];
double ans;//答案
int main(){
scanf("%d%d%d%d%d",&n,&A,&B,&C,a+1);
for(int i=2;i<=n;i++)
a[i]=((long long)a[i-1]*A+B)%100000001;
for(int i=1;i<=n;i++)
a[i]=a[i]%C+1;
for(ll i=2;i<=n;i++){//是2~n
ans+=1.0/max(a[i],a[i-1]);//公式
}
ans+=1.0/max(a[n],a[1]);//特殊处理
printf("%.3lf",ans);//输出
return 0;
}
尾声
如果你发现了问题,你可以直接回复这篇题解
如果你有更好的想法,也可以直接回复!

浙公网安备 33010602011771号