csp每日一练之出现次数最多的数

本文比较了两种不同编程语言实现的算法,一种是C++的简洁计数排序方法,另一种是C语言的复杂计数数组和下标查找。博主展示了如何通过高效的数据结构找出正整数数组中出现次数最多的数,同时介绍了优化思路和代码实现。
摘要由CSDN通过智能技术生成

试题编号: 201312-1
试题名称: 出现次数最多的数
时间限制: 1.0s
内存限制: 256.0MB
问题描述
  给定n个正整数,找出它们中出现次数最多的数。如果这样的数有多个,请输出其中最小的一个。
输入格式
  输入的第一行只有一个正整数n(1 ≤ n ≤ 1000),表示数字的个数。
  输入的第二行有n个整数s1, s2, …, sn (1 ≤ si ≤ 10000, 1 ≤ i ≤ n)。相邻的数用空格分隔。
输出格式
  输出这n个次数中出现次数最多的数。如果这样的数有多个,输出其中最小的一个。
样例输入
6
10 1 10 20 30 20
样例输出
10
自己写的通关代码::(运行环境c)
思路:
1.首先输入数据到数组a
2.在a中找出每个数后面有几个跟它相同的数并将这些数赋给b数组。
3.在b中找最大值,无论是1个还是多个,都将其下标赋给c数组
4.利用c中的值在a中查值,并赋给d数组
5.d中的最小值就是题目所求
例:输入5
1 1 2 2 2
那么
a:1 1 2 2 2
b:2 1 3 2 1
max=3;
c:2 default default default default (因为只有一个数,但申请了5个内存单元,所以后面的都是default 为0)
d: 2 default default default default (default 为0)
min=2;

#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i,j,s1=0,e=0,max,f=0,min;
int *a,*b,*c,*d;
scanf("%d",&n);
a=(int*)calloc(n,sizeof(int));//原数组
b=(int*)calloc(n,sizeof(int));//原数组中每个数后面有几个跟他相同的集合
c=(int*)calloc(n,sizeof(int));//相同数最多的下标构成的集合
d=(int*)calloc(n,sizeof(int));//c中的下标对应a中的值
for(i=0;i<n;i++)
{
 scanf("%d",a+i);
}	
for(i=0;i<n;i++)
{
	for(j=i;j<n;j++)
	{
		if(a[i]==a[j])
		{
			s1++;	
		}
	}
	b[i]=s1;
	s1=0;
}
max=b[0];
for(i=0;i<n;i++)
{
	if(max<b[i])
	{
		max=b[i];
	}
}
for(i=0;i<n;i++)
{
	if(max==b[i])
	{
		c[f]=i;
		f++;
		
	}
}

for(i=0;i<f;i++)
{
	d[i]=a[c[i]];
}
min=d[0];
for(i=0;i<f;i++)
{
	if(min>d[i]&&d[i]!=0)
		min=d[i];
}
printf("%d",min);
return 0;
}

看别人写的不错的代码:(c++)

#include<iostream>
#include<algorithm>
#include<string.h>//用了memset
using namespace std;
 
#define MAXN 10005
int s[MAXN];
 
bool cmp(int a,int b)
{
	return a>b;
}
 
int main()
{
	memset(s,0,sizeof(s));
	int n;
	while(scanf("%d",&n)!=EOF)
	{
	
		for(int i=0;i<n;i++)
		{
			int x=0;
			scanf("%d",&x);
			s[x]++;//存储x出现的次数
 
		}
		int sp[MAXN];
		memcpy(sp,s,sizeof(s));//数组s内容复制到数组sp中
		sort(sp,sp+MAXN,cmp);//次数从大到小排序
		int cnt=sp[0];//最大的出现次数
 
		for(int j=0;j<MAXN;j++)
		{
			if(s[j]==cnt) {printf("%d\n",j);break;}
		}
	
	}
	return 0;
}

他的思路:
用s[i]表示数字i出现的次数,算出出现次数最多的数cnt,遍历s数组,第一个满足s[i]等于cnt的i即为结果。
总结:不得不说,他的思路是真牛逼,考虑到输入有可能要输入重复数字,直接在输入的时候用数组下标代表数字本身,用该数组表示数字出现的频率,真是妙蛙种子进了奇幻妙妙屋——妙到家了。

java代码`

import java.util.*;

public class Main {
    public static void main(String[] args) {
    	Scanner sc=new Scanner(System.in);
    	
    	
    	int max=0,min=0;
    	int n=sc.nextInt();
    	int[] arr=new int[10001];
    	for(int i=0;i<n;i++)
    	{
    	 arr[sc.nextInt()]++;
    	}
    	for(int i=1;i<arr.length;i++)
    	{
    		if(arr[i]>max)
    		{
    			max=arr[i];
    			min=i;
    		}
    	}
    
    	 System.out.println(min);

    
    	

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JJpZh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值