洛谷P1012拼数,极简易懂算法(不用字符串)

博客内容介绍了如何通过计算每个数字出现的频率,来解决一个特殊的排序问题。作者提出了一种方法,首先建立两个数组,一个存储输入数据,另一个记录数据的频率。通过两两比较数字并更新频率,最后根据频率从大到小排序输出,从而得到正确顺序。这种方法避免了复杂的全排列暴力解题,且已通过所有测试用例。
摘要由CSDN通过智能技术生成

 初见这道题,相信很多人跟我一样是想通过寻找数的某种规律来实现选择性的排序,甚至使用全排列暴力解题,但是经过分情况考虑,这种方法需要考虑的情况太多,过于复杂,那么我们不妨从“频率“的角度入手。

首先建一个数组a来装输入的数据,再建一个数组b来记录a中对应元素的”频率“,b数组初始化全为0。

接下来进入正题,比如我们有两个数——2和10。根据题目,210>102,所以2应该放在10之前。因此我们将输入的n个数两两作比较,每次比较后,应该放在前面的那个数的频率+1(也就是b数组中对应的数+1)。这样比较了n-1次后,我们不难发现,有一个数的频率变成了n-1(就是说它应该放在所有数的前面),那么这个数理应放在第一位,还有的数的频率变成了n-2(说明它只应该放在第一个数的后面),那么这个数应该放在第二位...........如此递推,频率的大小也就决定了数据应该放的位置。我们根据a中数据的对应频率给a中数据从大到小排序,依次输出,就是我们想要的结果了。

#include <stdio.h>
#include <math.h>
int posnum(int x)//判断数据位数的函数
{
	int i;
	for (i = 1; i <= 20; i++)
	{
		if (x / pow(10, i) < 1)
		{
			break;
		}
	}
	return i;
}
int main()
{
	int n, a[20];
	int b[20] = { 0 };
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
	}
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			if (a[i] * pow(10, posnum(a[j])) + a[j] > a[j] * pow(10, posnum(a[i])) + a[i])
				//此循环判断谁该放在前面
			{
				b[i]++;
			}
			else
			{
				b[j]++;
			}
		}
	}
	for (int i = 0; i < n - 1; i++)//根据频率(b)从大到小将a排序
	{
		for (int j = 0; j < n - 1; j++)
		{
			if (b[j] < b[j + 1])
			{
				int temp = a[j + 1];
				a[j + 1] = a[j];
				a[j] = temp;
				int temp2 = b[j + 1];
				b[j + 1] = b[j];
				b[j] = temp2;//别忘了a排序的时候b要跟a同步排序(数据是对应的)
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		printf("%d", a[i]);
	}
}

 (该种方法已通过洛谷所有组数据)

如有不对之处,还请多多指正!谢谢!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值