你好!!!!我是潮倾
今天做的是
其实这道题标的是贪心,但是我其实对贪心掌握的不是很好,做这道题我用到了结构体和冒泡排序
先来看一下我的代码吧,代码后面写了我的思路,让我很开心的是这次一遍就过了!!!!!连调试都没有!!!
#include<stdio.h>
#include<stdlib.h>
int sum=0;
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] < arr[j + 1]) {
// 交换 arr[j] 和 arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}//应该是换完之后,从da到xiao排列
struct Num
{
int bi[200005];
int bicount;
};
//结构体的成员变量应在main函数里面初始化,而不是在结构体里面
int main()
{
struct Num num[10];
int n;
scanf("%d",&n);
for(int i=0;i<10;i++){
num[i].bicount=0;
}
for(int j=0;j<n;j++)
{
int m,l;
scanf("%d %d",&m,&l);
num[m].bi[num[m].bicount]=l;
num[m].bicount++;
}
for(int i=0;i<10;i++){
bubbleSort(num[i].bi,num[i].bicount);
}
int rest;
rest=n/10;
for(int x=0;x<10;x++)
{
if(num[x].bicount==0)
{
//说明它不需要改
}
else
{
while(num[x].bicount>rest)
{
sum=sum+num[x].bi[num[x].bicount-1];
num[x].bicount--;
}
}
}
printf("%d",sum);
}
首先我们这道题
他说给的数据会是10的倍数,然后在输入的这些数据里面,我们不用管他们最后改成了什么数字,最后肯定是改成了0123456789这十个数字,让他们在这组数中是同样个数。把这些数存起来的的话,我们先看看题中给的这组样例
数字 | 出现次数 | 第一次出现的修改次数 | 第二次出现的修改次数 | 第三次出现修改次数 | 第?次出现的修改次数 |
0 | 0 | 0 | |||
1 | 3 | 1 | 2 | 3 | |
2 | 3 | 4 | 5 | 6 | |
3 | 3 | 7 | 8 | 9 | |
4 | 1 | 10 | |||
5 | 0 | ||||
... | ... | ||||
9 | 0 |
全局变量sum 用来记录我们的最终结果
struct Num num[10];
定义结构体数组来存储数字0-9
struct Num {
int bi[200005];
int bicount; };
这一段是我们根据上面的表格,我们需要记录0-9,需要记录它们在这组数据中出现的次数,需要记录每一个数字他的那些需要修改所花的代价,把每一个代价都记录在对应数字的名下我们才能更好地找到最少代价。
for(int i=0;i<10;i++){
num[i].bicount=0;
}
我们在结构体初始化的时候要注意在主函数里面初始化,而不是在定义结构体的时候(因为我当时编译错误了救命)
for(int j=0;j<n;j++)
{
int m,l;
scanf("%d %d",&m,&l);
num[m].bi[num[m].bicount]=l;
num[m].bicount++;
}
输入数据,对于bicount,始终要记得他是num[0-9].bicount,他给每个数都要记录
for(int i=0;i<10;i++){
bubbleSort(num[i].bi,num[i].bicount);
}
然后我们给那些代价排序,我是按从大到小来排的,也就是拿样例来说的话,现在变成了
数字 | 出现次数 | 第一次出现的修改次数 | 第二次出现的修改次数 | 第三次出现修改次数 | 第?次出现的修改次数 |
0 | 0 | 0 | |||
1 | 3 | 3 | 2 | 1 | |
2 | 3 | 6 | 5 | 4 | |
3 | 3 | 9 | 8 | 7 | |
4 | 1 | 10 | |||
5 | 0 | ||||
... | ... | ||||
9 | 0 |
int rest;
rest=n/10;
因为数据是10的倍数,所以我们要算一下每一个数字要留几个,就是说现在是10个数,0123456789每个就要最后改成每个数只出现一次,20个数,最后就要112233445566778899每个数留下两个
那我们要留下几个数呢?当然是n/10个啦
而刚才我们也记录了每个数字出现了几次,所以
for(int x=0;x<10;x++)
{
if(num[x].bicount==0)
{
//说明它不需要改
}
else
{
while(num[x].bicount>rest)
{
sum=sum+num[x].bi[num[x].bicount-1];
num[x].bicount--;
}
}
}
如果我们num[?].bicount=0,说明这个数字没用,没出现,我们什么都不用做,如果不是0,我们看num[?].bicount>rest,那么他的出现次数就多了,我们要改,刚好经过冒泡排序之后,最后面的是最小的,我们也不用修改什么,只要倒着开始加,加需要的个数就行,而倒着的那个下标是bicount-1
好啦,今天的分享就到这里,我们继续加油(ง •_•)ง