题解 P7259 【[COCI2009-2010#3] SORT】

题意

给定一个原始序列,按题目要求排序:

1.1. 按在序列中出现的次数从大到小排序。

2.2. 若次数相同,则按在原始序列出现的位置从小到大排序。

3.3. 相同的元素排序后一定连在一起。(观察样例可得)

所以,题目怎么说我们就怎么做

分析

因为涉及排序的变量有很多个,所以我们可以把他们统一放在一个 struct 结构体里面,根据题意,每个元素涉及的变量有:

1.1. 元素本身的值 vv

2.2. 元素在序列中出现的次数 cntcnt

3.3. 元素在序列中第一次出现的位置 firstfirst

在输入的过程中,我们只需在已有的结构体里寻找这个元素是否已经存入过,若找到,则将元素在序列中出现的次数 +1+1,否则新建一个结构体,此时这个元素只出现了一次,所以将 cntcnt 赋值为 11,而 firstfirst 就是当前循环中的 ii

for(int i=1;i<=n;i++)
{
	cin>>x;
	flag=1;//flag存储是否在已有结构体中找到相应元素 
	for(int j=1;j<=m;j++)//在当前m个结构体当中寻找 
	{
		if(a[j].v==x)//找到 
		{
			a[j].cnt++;//这个元素又出现了一次 
			flag=0;//找到了则将flag标记为0 
			break;
		}
	}
	if(flag)//没找到 
	{
		//新建一个
		a[++m].first=i;//第一次是在i处出现 
		a[m].cnt=1;//只出现了一次 
		a[m].v=x;//元素本身的值 
	}
}

接下来是排序,标题已经告诉我们sort,不过需要自己写一个比较函数,只要跟着题意的步骤写就行了。

bool cmp(asdf x,asdf y)//asdf是结构体名称
{
	return (x.cnt>y.cnt||(x.cnt==y.cnt&&x.first<y.first));
  //按次数较大或次数一样且位置靠前排序
}

排好序后就要输出,输出时从小到大循环一遍结构体,对于每个结构体,只需输出 cntcntvv

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,c,x,m;//m为结构体个数,初始为0 
struct asdf
{
	int v;//元素本身的值
	int cnt;//元素在序列中出现的次数
	int first;//元素在序列中第一次出现的位置
}a[N];
bool flag;
bool cmp(asdf x,asdf y)
{
	return (x.cnt>y.cnt||(x.cnt==y.cnt&&x.first<y.first));
	//按次数较大或次数一样且位置靠前排序
}
int main()
{
    cin>>n>>c;
    for(int i=1;i<=n;i++)
    {
    	cin>>x;
    	flag=1;//flag存储是否在已有结构体中找到相应元素 
    	for(int j=1;j<=m;j++)//在当前m个结构体当中寻找 
    	{
    		if(a[j].v==x)//找到 
			{
				a[j].cnt++;//这个元素又出现了一次 
				flag=0;//找到了则将flag标记为0 
				break;
			}
		}
		if(flag)//没找到 
		{
			//新建一个
			a[++m].first=i;//第一次是在i处出现 
			a[m].cnt=1;//只出现了一次 
			a[m].v=x;//元素本身的值 
		}
	}
	sort(a+1,a+m+1,cmp);//将m个结构体排序 
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=a[i].cnt;j++)//第二层循环cnt次 
		{
			cout<<a[i].v<<" ";
		}
	}
	return 0;
}

PS:个人感觉 CC 没有任何用处删了算了

posted @ 2021-02-24 07:11  luckydrawbox  阅读(14)  评论(0)    收藏  举报  来源