Problem P23. 计数排序(使用C/C++)
计下标从 1 开始。有n 个取值范围在 [1,m] 的整数ai 。请将它们升序排序,设排序后数组为b 。为避免输出过长,请输出:
输入
输出
输出一个整数代表计算结果
样例
标准输入
10 3
1 2 3 2 2 3 3 1 3 3
标准输出
147
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define mn 10000005
/*
全局变量初始值默认0
a:储存数字
b:储存排序后的数组
c:计算数组a中每个数字出现的次数
n:n个数字
m:数字大小范围在1-m内
*/
int a[mn], b[mn], c[mn], n, m, bi, mod = 1e9 + 7;
long long ans;
int main()
{
cin >> n >> m;
for(int i=1; i<=n; i++)//读取n个数字
{
scanf("%d", &a[i]);
c[a[i]]++;//ai这个数字出现的次数
}
for(int i=1; i<=m; i++)//对数组a中数字排序,数组a中的数字只有1-m;
{
for(int j=1; j<=c[i]; j++)//排序好储存在新数组b中
{
b[++bi] = i;//bi初始默认值为0,这里从b[1]开始的,所以用++bi;
}
}
for(int i=0; i<=n; i++)//输出公式的求和
{
/*
复合赋值运算符“%=”,
表示的意思是先将运算符左边操作数指向的变量值和右边的操作数执行取余操作,
然后再将取余的结果赋值给左边的操作数指向的变量
*/
(ans += 1LL * i * b[i]) %= mod;
}
cout << ans;
// cout << "Hello world!" << endl;
return 0;
}
自我练习,二刷
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define mn 10000005
/*
abc数组分别表示:储存n个数字,储存排序后的数组,统计a中数字出现的次数;
n:n个数字
m:数字范围1-m
bi:暂存b数组中的位置
mod:无限大
全局变量,默认值为0;
*/
int a[mn], b[mn], c[mn], n, m, bi, mod=1e9+7;
long long ans;
int main()
{
cin >> n >> m;
//读取数组
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
c[a[i]]++;//统计ai这个数字出现的次数
}
//排序
for(int i=1; i<=m; i++)//数字出现的范围是1-m,从1开始排序,一直到m
{
for(int j=1; j<=c[i]; j++)//i这个数字出现了多少次,就排多少个
{
b[++bi] = i;//bi默认为0,++bi后即为1;
}
}
//输出累乘后,完成题目该公式的结果
for(int i=1; i<=n; i++)
{
//1LL:强制转换为long long类型
(ans += 1LL*i*b[i]) %= mod;
}
cout << ans;
// cout << "Hello world!" << endl;
return 0;
}