鼠鼠的专属宝盒
鼠鼠的专属宝盒
一、目的
-掌握malloc用法
-掌握二维数组
二、实验内容与设计思想
鼠鼠的专属宝盒
鼠鼠有 M 个宝盒。
每个宝盒只能放一种颜色的彩球,一种颜色彩球只能被放在一个宝盒里(一对一)。
每个宝盒的容量是有限的,最多放 K 个彩球。
现在有 N 个彩球滚向鼠鼠,每个彩球都有一个颜色Ci,鼠鼠会按顺序地拿起彩球。
当鼠鼠拿起一颗彩球后会进行以下判断:
如果鼠鼠还没拿过这种颜色的彩球
如果有空闲的宝盒,那鼠鼠就会将这颗彩球放到一个空闲的宝盒中,该宝盒变成这种颜色彩球的专属宝盒
如果没有空闲的宝盒,那么鼠鼠就会这颗彩球扔掉
如果鼠鼠拿过这种颜色的彩球
如果这种颜色的专属宝盒还没放满 K 个,鼠鼠就会将其放到这个专属宝盒里面
如果这种颜色的专属宝盒已经放满了 K 个,那么鼠鼠就会这颗彩球扔掉
鼠鼠想要知道所有宝盒中的彩球总共有多少个,同时他想知道已经使用的专属宝盒有多少个,你能帮帮他吗?
输入格式
第一行输入三个正整数 N,M,K ,表示 N 彩球的总数量,M 是专属宝盒的数量,K 表示每个专属宝盒的容量。
第i个数Ci表示第 i 个球的颜色。
输出格式
输出两个整数,第一个整数表示所有宝盒的彩球总数,第二个整数表示已经使用的专属宝盒数量。
输入样例 1
7 3 2
1 2 1 3 2 3 2
输出样例 1
6 3
输入样例 2
12 3 3
1 2 3 4 1 2 3 4 2 3 4 2
输出样例 2
8 3
输入样例 3
5 2 4
1 1 1 2 1
输出样例 3
5 2
样例解释:
对于第一个样例:
第一颗彩球颜色为 1,鼠鼠放到第一个宝盒中,每个宝盒放球情况为 [1,0,0]
第二颗彩球颜色为 2,鼠鼠放到第二个专属宝盒,每个宝盒放球情况为 [1,1,0]
第三颗彩球颜色为 1,鼠鼠找到颜色 1 的专属宝盒,也就是第一个宝盒,并且盒内彩球的数量小于宝盒的容量 K,可以放入,每个宝盒放球情况为 [2,1,0]
第四颗彩球颜色为 3,鼠鼠放到第三个宝盒中,每个宝盒放球情况为 [2,1,1]
第五颗彩球颜色为 2,找到颜色 2 的专属宝盒,也就是第二个宝盒,并且盒内彩球的数量小于宝盒的容量 K,可以放入,每个宝盒放球情况为 [2,2,1]
第六颗彩球颜色为 3,找到颜色 3 的专属宝盒,也就是第三个宝盒,并且盒内彩球的数量小于宝盒的容量 K,可以放入,每个宝盒放球情况为 [2,2,2]
第7个球没有宝盒可用了
所以最后所有的专属宝盒内的彩球数量为 6,用了 3 个专属宝盒
数据范围
对于 50% 的数据,1≤N≤100, 1≤M,K≤N
对于 100% 的数据,1≤N≤1000, 1≤M,K≤N, 1≤Ci≤N
题目分析:
看题目可知,代码量大概并不复杂,重点在于要记得转换字符并正确存储值,不重复存储
函数相关伪代码
1.scanf("%d %d %d",&n,&m,&k1);
2.int b[m][2];
for(i=0;i<m;i++)
|b[i][0]=0;
|b[i][1]=0;
3.for(i=0;i<n;i++)
|scanf("%d",&a[i]);
|if(p<m){
||for(k=0;k<p;k++)
||if(a[i]==b[k][0])
||| break;
|if(k==p)
||b[p][0]=a[i];
||p++;
4.for(i=0;i<p;i++)
|for(k=0;k<n;k++)
||if(b[i][0]==a[k]&&b[i][1]<k1)
|||b[i][1]++;
|||sum++;
函数代码
#include<stdio.h>
int main()
{
int n,m,k,sum=0,p=0,i,k1;
scanf("%d %d %d",&n,&m,&k1);
int a[n];
int b[m][2];
for(i=0;i<m;i++){
b[i][0]=0;
b[i][1]=0;
}
//int (*b)[2] = malloc(sizeof(int[m][2]));
for(i=0;i<n;i++){
scanf("%d",&a[i]);
if(p<m){
for(k=0;k<p;k++){
if(a[i]==b[k][0]){
break;
}
}
if(k==p){
b[p][0]=a[i];
p++;
}
}
}
for(i=0;i<p;i++){
for(k=0;k<n;k++){
if(b[i][0]==a[k]&&b[i][1]<k1){
b[i][1]++;
sum++;
}
}
}
printf("%d %d",sum,p);
return 0;
}
三、实验使用环境
以下请根据实际情况编写
- 操作系统:Windows 11专业版
- 编程语言:C
- 开发工具:[DevC++]
四、实验步骤和调试过程
鼠鼠的专属宝盒
本机运行截图
运行分析
第一行第一个数表示总球数,第二个表示月光宝盒数,第三个表示宝盒内存,输入时要以空格来分隔数,使用逗号会使代码运行报错,提前结束运行。
第二行表示小球颜色,也要以空格来表示间隔。
第三行表示使用的宝盒数和装入盒中的小球数,按照题目样例输出要用空格来表示间隔。
五、实验小结
遇到的问题及解决方法:
- 问题:代码逻辑有问题
- 解决方法:修改代码
实验体会和收获:
代码中首先定义了几个int型变量和两个数组a和b,其中b是一个二维数组,用于存储数组a中不同元素的值(颜色)和它们颜色的出现次数(为了判断是否超出宝盒内存),我是直接定义b为int b[m][2],m是动态变量,我不可以直接使其初始化为0,需要通过循环使其初始化,当然,为了节省时间,可以把b写成int (*b)[2] = malloc(sizeof(int[m][2])),这就已经初始化了,不需要循环。
之后通过双重循环遍历数组a,将所有球的颜色存在a中,再将不同的元素存储在数组b[i][0],如果某个元素(颜色)在数组b[i][0]中已经存在,则不再存储。然后,再次遍历数组b和a,用b[i][1]来储存宝盒内存的使用情况(这种对应关系可以用c++中的map来存储,可以提高效率)(统计出现次数小于k1的元素的总出现次数),判断条件之所以是b[i][1]<k1,而不是小于k1+1是因为我通过这个条件后要在宝盒内存上加1,所以不可以是k1+1,并输出这个总次数和数组b中不同元素的数量(即使用宝盒数)。
最后输出sum(所有宝盒里的球数)和p(因为我在b中每加入一种颜色,p就要+1,所以其实际上比b中使用行数的最大下标大一,刚好就是使用行数,即使用宝盒数)。