18. 吃货

郭老师特别喜欢美食,是个典型的吃货,无聊的时候就会打开大众点评搜寻美食,每次都会选择几家综合评分高的餐厅满足口福,但他最近发现手机里面的大众点评软件貌似不好用了,没办法按照评分进行排序,所以每次都要从上翻到下找出评分最高的几家餐厅,很是苦恼。

现在请大家帮忙在纷繁众多的餐厅中找出评分最高的 m 个,推荐给郭老师。

输入

输入的第一行 n m 为正整数,n 表示餐厅的数目,m 表示需要找出的餐厅个数,1 ≤ m, n ≤ 10000000。随后的 n 行为 n 家餐厅的评分,范围为1~10000000的正整数。

输出

输出为 m 行,每行为餐厅的评分,评分按降序排列。


测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 10 3↵
  2. 10↵
  3. 9↵
  4. 3↵
  5. 7↵
  6. 2↵
  7. 6↵
  8. 7↵
  9. 1↵
  10. 9↵
  11. 8↵
以文本方式显示
  1. 10↵
  2. 9↵
  3. 9↵
1秒1024KB0



//由于此题数据量一部分较小一部分较大,故根据不同数据量使用不同的排序方法
//对数据量较小的可以一遍输入一遍取缔输出数组NumStr[]中的最小值,同时注意对NumStr[]的及时维护
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>

int NumStr[1000] = { 0 };
void Judge(int sum,int m)
{
	int flag = 0;
	if (NumStr[0] > sum)
		return;
	for (int i = 1; i < m; i++)
	{
		if (NumStr[i] >= sum)
		{
			NumStr[i - 1] = sum;
			flag = 1;
			break;
		}
		else
			NumStr[i - 1] = NumStr[i];	
	}
	if (!flag)//把这个判断条件从else里拿出来后就A了,不然有一个WA和一个TLE,很是奇怪
		NumStr[m - 1] = sum;
}
int main(void)
{
	int n, m, t;
	scanf("%d %d", &n, &m);
	getchar();
	char ch;
	int sum;
	if (m < 500000)
	{
		memset(NumStr, 0, sizeof(NumStr));
		for (int i = 0; i < n; i++)
		{
			sum = 0;
			while (1)
			{
				ch = getchar();
				if (ch >= '0'&&ch <= '9')
					sum = sum * 10 + (ch - '0');
				else break;
			}
			Judge(sum,m);
		}
		for (int i = m - 1; i >= 0; i--)
		{
			if (NumStr[i] != 0)
				printf("%d\n", NumStr[i]);
		}
			
	}
	else
	{
		char *Str_Num = (char *)calloc(10000001, 2);
		for (int i = 0; i < n; i++)
		{
			sum = 0;
			while (1)
			{
				ch = getchar();
				if (ch >= '0'&&ch <= '9')
					sum = sum * 10 + (ch - '0');
				else break;
			}
			Str_Num[sum]++;
		}
		for (int i = 10000000;; i--)
		{
			if (m == 0||i==0) 
				break;
			if (Str_Num[i] != 0)
				for (int j = 0; j < Str_Num[i]; j++)
				{
					printf("%d\n", i);
					m--;
					if (m == 0)
						break;
				}
		}
	}

	return 0;
}


还有一种写法(同学的)我就是看他的才有的思路,为了防止查重,把递归写法改成了循环
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>

int judge(int p, int i);

int mm[20000];
int main(void)
{
	int n, m,t;
	scanf("%d %d", &n, &m);
	getchar();
	char ch;
	int sum;
	if (m < 400000)
	{
		for (int i = 0; i < n; i++)
		{
			sum = 0;
			while (1)
			{
				ch = getchar();
				if (ch >= '0'&&ch <= '9')
				{
					sum = sum * 10 + (ch - '0');
				}
				else break;
			}
			judge(sum, m - 1);
		}
		for (int i = 0; i < m; i++)
		{
			printf("%d\n", mm[i]);
		}
	}
	else
	{
		char *s = (char *)calloc(10000001, 2);
		for (int i = 0; i < n; i++)
		{
			sum = 0;
			while (1)
			{
				ch = getchar();
				if (ch >= '0'&&ch <= '9')
				{
					sum = sum * 10 + (ch - '0');
				}
				else break;
			}
			s[sum]++;
		}
		for (int i = 10000000;; i--)
		{
			if (m == 0) break;
			while (s[i]--)
			{
				printf("%d\n", i);
				m--;
			}
		}
	}
	return 0;
}

int judge(int p, int i)
{
	if (i == 0 && p > mm[i])
	{
		int y;
		y = p;
		p = mm[i];
		mm[i] = y;
		return p;
	}
	else if(p>mm[i])
	{
		int b = judge(p, i - 1);
		int y;
		y = b;
		b = mm[i];
		mm[i] = y;
		return b;
	}
	else
	{
		return p;
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值