华南理工大学“三七互娱杯”程序设计竞赛(重现赛)( HRY and array 高精度除法模板)
题目链接:https://ac.nowcoder.com/acm/contest/874/D
题目大意:给你两个数列a和b然后对a可以进行排列,对b可以任意排列,问你sigma(a(i)*b(i))的期望。
具体思路:求期望的时候我们分着进行就可以了,对于a数组,排列方式有n!种,对于b数组,我们每一次固定一个,然后这个的期望就是(n-1)!/(n)!,也就是1/n,但是这只是一个的,我们把所有的情况相加就可以了。
注意保留30位小数需要用到模拟除法,就是每一次*10,然后取余模数。这个题还需要考虑四舍五入,最后一位特判即可。
AC代码:
1 #include<iostream>
2 #include<stdio.h>
3 #include<cmath>
4 #include<string>
5 #include<cstring>
6 #include<bits/stdc++.h>
7 #include<algorithm>
8 using namespace std;
9 # define ll long long
10 # define inf 0x3f3f3f3f
11 const int maxn = 2e6+100;
12 const int mod = 1e9;
13 ll a[maxn];
14 ll b[maxn];
15 ll sto[maxn];
16 void cal(ll sum,ll n,int num)
17 {
18 int pos=0;
19 sto[++pos]=sum/n;
20 sum%=n;
21 num++;
22 while(num--)
23 {
24 sum*=10ll;
25 sto[++pos]=sum/n;
26 sum%=n;
27 }
28 if(sto[32]>=5){
29 sto[31]++;
30 }
31 for(int i=31;i>=2;i--){
32 sto[i-1]+=sto[i]/10;
33 sto[i]%=10;
34 }
35 cout<<sto[1]<<'.';
36 for(int i=2;i<=31;i++){
37 cout<<sto[i];
38 }
39 cout<<endl;
40 }
41 int main()
42 {
43 // freopen("hqx.out","w",stdout);
44 int T;
45 scanf("%d",&T);
46 while(T--)
47 {
48 ll n;
49 scanf("%lld",&n);
50 ll sum1=0,sum2=0;
51 for(ll i=1; i<=n; i++)
52 {
53 scanf("%lld",&a[i]);
54 sum1+=a[i];
55 }
56 for(ll i=1; i<=n; i++)
57 {
58 scanf("%lld",&b[i]);
59 sum2+=b[i];
60 }
61 sum1*=sum2;
62 cal(sum1,n,31);
63 }
64 return 0;
65 }