使用c++设计:有一个数组a有n个元素,把数组中的0等概率替换成1~m的某个数,然后对数组排序,计算第k个位置的数,就是ak,计算ak的期望(不能使用rand()函数,确切的计算出来),并对结果mod998244353,输入是n,m,k,以及数组的n个值,使用O(n^2logn)以内的算法设计
时间: 2023-05-29 12:02:33 浏览: 292
思路:
首先需要计算出一个数被选中替换为另一个数的概率。假设数组a中0的个数为x,则选中一个0替换成另一个数的概率为1/x。每个非0元素被选中替换成另一个数的概率为0。所以,对于一个非0元素ai,它最终不变留在原位的概率为(1-1/x)^x,被替换到其他位置的概率为1-(1-1/x)^x。
接着,需要计算出ai最终留在原位的期望值E(ai)和ai被替换到其他位置的期望值E(ai')。E(ai)可以通过二项式定理展开后取极限得到,结果为1/(1-1/x)。E(ai')可以直接计算,结果为(ai + 1 + ... + m) / x。所以,ai最终替换成什么数对期望的贡献为(ai + 1 + ... + m) / (x * (1-1/x))。
最后,对于排序后的数组a,第k个位置的数ak就是a[k-1]。ak的期望值E(ak)可以通过对每个元素的期望贡献进行求和得到。所以,E(ak) = (a[0] + 1 + ... + m) / (n * (1-1/x)) + ... + (a[n-1] + 1 + ... + m) / (n * (1-1/x))。将结果对998244353取模即可。
算法具体实现:
首先统计数组a中0的个数x,并对其进行计数排序,得到有序数组b。然后依次遍历b中的每个元素,计算出每个元素在原数组a中的出现次数cnt[i]以及该元素最终替换成另一个数对期望的贡献con[i]。最后,对每个位置i,计算期望贡献的总和即可得到E(ak)。
代码实现如下:
相关问题
使用c++设计:有一个数组a有n个元素,把数组中的0等概率替换成1~m的某个数,计算第k个位置的数,就是ak,计算ak的期望,并对结果mod998244353,输入是n,m,k,以及数组的n个值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define mod 998244353
int main() {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
int *a = (int *) malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int c1 = 0, c0 = 0;
srand((unsigned) time(NULL));
for (int i = 0; i < n; i++) {
if (a[i] == 0) {
if (rand() % 2 == 1) {
a[i] = rand() % m + 1;
c1++;
} else {
c0++;
}
}
}
int *cnt = (int *) calloc(m + 1, sizeof(int));
for (int i = 0; i < n; i++) {
cnt[a[i]]++;
}
int f[m + 1];
f[0] = 1;
for (int i = 1; i <= m; i++) {
for (int j = c1; j >= cnt[i]; j--) {
f[j] = (f[j] + f[j - cnt[i]]) % mod;
}
}
int ans = 0;
for (int i = k - c0; i <= c1; i++) {
if (i < 0 || i > m) {
continue;
}
ans = (ans + (long long) f[i] * (m - i + 1)) % mod;
}
printf("%d\n", ans);
free(a);
free(cnt);
return 0;
}
用c++设计程序,把一个数组的0等概率换成1~m,排序后计算ak的数的期望
要实现这个程序,我们需要使用以下步骤:
1. 读取数组元素个数n和0被替换成的最大值m。
2. 声明一个长度为n的整型数组,并用随机数生成器将其填充为0或1。
3. 遍历该数组,将每个0替换为1-M之间的任意一个整数。
4. 对原始数组和修改后的数组进行快速排序。
5. 遍历排序后的数组,统计出现次数最多的元素ak。
6. 计算ak出现的次数除以n,得到ak的期望值。
下面是使用C语言实现此程序的示例代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_M 100
// 生成1到m之间的随机整数
int random_int(int m) {
return rand() % m + 1;
}
// 交换数组中两个元素的值
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 快速排序
void quick_sort(int *arr, int left, int right) {
if (left >= right) return;
int i = left, j = right, pivot = arr[left];
while (i < j) {
while (i < j && arr[j] >= pivot) j--;
if (i < j) arr[i++] = arr[j];
while (i < j && arr[i] < pivot) i++;
if (i < j) arr[j--] = arr[i];
}
arr[i] = pivot;
quick_sort(arr, left, i - 1);
quick_sort(arr, i + 1, right);
}
// 计算ak的期望值
double calc_expectation(int *arr, int n, int ak) {
int count = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == ak) count++;
}
return (double)count / n;
}
int main() {
int n, m, arr[MAX_M], modified[MAX_M];
double sum = 0.0;
// 读取数组大小和0被替换成的最大值
printf("Enter array size and maximum value of modified 0s: ");
scanf("%d%d", &n, &m);
// 初始化随机数生成器
srand(time(NULL));
// 填充原始数组并进行修改
for (int i = 0; i < n; i++) {
arr[i] = rand() % 2;
if (arr[i] == 0) arr[i] = random_int(m);
}
// 复制数组并排序
for (int i = 0; i < n; i++) {
modified[i] = arr[i];
}
quick_sort(arr, 0, n - 1);
quick_sort(modified, 0, n - 1);
// 找到出现次数最多的元素ak
int ak = modified[n-1], count = 1, max_count = 1;
for (int i = n - 2; i >= 0; i--) {
if (modified[i] == ak) {
count++;
} else {
if (count > max_count) {
max_count = count;
ak = modified[i+1];
}
count = 1;
}
}
if (count > max_count) {
max_count = count;
ak = modified[0];
}
// 计算ak出现的期望值
sum = calc_expectation(arr, n, ak);
// 输出结果
printf("The original array is:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
printf("The modified array is:\n");
for (int i = 0; i < n; i++) {
printf("%d ", modified[i]);
}
printf("\n");
printf("The number with highest frequency is %d\n", ak);
printf("The expectation of this number's occurrence is %f\n", sum);
return 0;
}
```
阅读全文
相关推荐















