Wannafly挑战赛3【solved : 3 / 5】

来源:互联网 发布:西南交大希望学院网络 编辑:程序博客网 时间:2024/04/27 14:01

A 珂学送分(概率)

给你一个长 n 的序列,m 次查询每次查询给一个 x,然后:从序列的最左端 1 开始,每次随机的选择一个右端点 r,如果两个端点间的区间和不超过 x ,就进行一次分割,然后把左端点变成 r + 1, 否则一直随机下去。问这样分割出来的期望段数

思路:假设f(x)[xn],假设x的分割极限最右是y,那么显然可以得到f(n)=yi=x+1f(i)。那么我们可以倒过来递推这个递推式,用一个后缀和维护一下即可。

#include <bits/stdc++.h>using namespace std;const int maxn = 100000 + 5;int a[maxn], maxJ[maxn];double f[maxn],  suffixSum[maxn];int main(){    int n, m;    scanf("%d%d", &n, &m);    for(int i = 0; i < n; i++) scanf("%d", &a[i]);    for(int i = 0; i < m; i++)    {        int x;        scanf("%d", &x);        if(x < *max_element(a, a + n))        {            puts("YNOI is good OI!");            continue;        }        int mx = 0, sum = 0, p = 0;        for(int i = 0; i < n; i++)        {            while(p < n && sum + a[p] <= x) sum += a[p], p++;            maxJ[i] = max(i, p);            sum -= a[i];        }        f[n - 1] = suffixSum[n - 1] = 1;        for(int i = n - 2; i >= 0; i--)        {            int lb = i, rb = maxJ[i];            f[lb] = (suffixSum[lb + 1] - suffixSum[rb + 1]) / (rb - lb) + 1;            suffixSum[i] = suffixSum[i + 1] + f[i];        }        printf("%.2f\n", f[0]);    }    return 0;}

B 遇见

A和B在同一条路上,他们之间的距离为 k 米。A现在想见到B,所以A开车以 x km/h的速度朝着B的方向行驶,同时B也以 y km/h的速度朝着A的方向走去。A的车有 n 个档位,每个档位有不同的速度。现在假设A开车去见B,求他最快和最慢在几秒后能见到B。

#include <bits/stdc++.h>using namespace std;const int maxn = 100000 + 5;int a[maxn];int main(){    int n, m, k;    scanf("%d%d%d", &n, &m, &k);    for(int i = 0; i < n; i++)   scanf("%d", &a[i]);    sort(a, a + n);    printf("%d %d\n",(int)ceil(3.6*k/(m + a[n-1])), (int)ceil(3.6*k/(m + a[0])));    return 0;}

C 位数差

给一个数组{a},定义 h(a,b)为在十进制下 a + b 与 a 的位数差,求 1i<jnh(aiaj),0的位数为1。 1n1e50ai1e8

思路:
  trick点是我有点没想明白两个1e8相加还能到1e9?。- - 居然判断到了九位的时候。
  然后考虑到求h(a,b)的时候可以单独求a的位数和b的位数,然后所有的b的位数的贡献可以在一开始的时候维护出来。那么a的 位数的和 ,就是所有数对的加和的位数的和,那么就和顺序无关,就能从无序变成有序,排序以后,枚举每个位数,二分一下数量即可。

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5 + 5;int a[maxn];long long mi[maxn];int bit(int num){    if(num == 0)    return 1;    int ret = 0;    while(num)  num /= 10, ret++;    return ret;}int main(){    mi[0] = 0, mi[1] = 1;    for(int i = 2; i <= 10; i++) mi[i] = mi[i -1] * 10;//    int n;    scanf("%d", &n);    long long ans = 0;    for(int i = 0; i < n; i++)    {        scanf("%d", &a[i]);        ans -= 1LL * bit(a[i]) * (n - i - 1);    }    sort(a, a + n);    for(int i = 0; i < n; i++)    {        for(int j = 0; j <= 9; j++)        {            long long num = lower_bound(a + i + 1, a + n, mi[j + 1] - a[i]) - lower_bound(a + i + 1, a + n, mi[j] - a[i]);            ans += 1LL * (j == 0 ? 1 : j) * num;        }    }    printf("%lld\n", ans);    return 0;}
原创粉丝点击