排名结构体练习(c/c++)
可知:
要求:
分析:
容易发现 a 的顺序对答案无影响,(虽然最后是按照a的输入顺序打印,但我们可以用结构体将这个一顺序存储起来,最后按照结构体存储的顺序打印出来),所以我们先将 a 从大到小排序,i的顺序的
上图为:f(p)<=k<=g(p); 注: ,当然 p<=q ;所以f(i)<=g(i)
因为F(i);和G(i);都是表示个数;所以将a[]从大到小排列,然后F,G都可以用 a [ ] 排序后的序号来表示;也方便与数字k做比较;
F(i) = i ;(排序后的序号) , (虽然不包括ai但等于大于 的数+1,所以还是F(i)=i)
所以 F(k) = k (临界值) ---F(i) 表示:比ai大的个数+1
G(i) = q ;(G(i)=F(i)+与 相等的个数)
所以可以知道 G(i)>=F(i)一定存在
所以题目要求就是 i <= k <= q;
方法:
思想:
(i从0 到 n 依次+1)
- i<k; 就是F(i)<k,所以还需要G(i)>k;,如果G(i)>=k;不用操作;如果G(i)<k; 需要将G(i)变成>=k;最少的操作一定是变成相等的,所以任务就是变成G(i)=k,
- i=k, 就是F(i)=k,因为 G(i)>=F(i), 所以F(i)=k<=G(i); 不需要操作;now=0;
- i>k, 就是F(i)>k ;需要将F(i)变成<=k;z最少的操作一定是变成相等的,所以任务就是变成F(i)=k,
具体步骤:
1.要使G(i)>=F(i);就是将 第 i个~~~第k个;全变成与ai相等的数;
方法:①()+()```````````(-)
方法:② 将ai~ak全看成ai(和是
*(k-i+1))减去自己原来的值()
2.不需要操作;now = 0;
3.F(i)增加到 k ;也就是将 长大到就好了;因为对应的F(k)=k;注:自己变大了比自己大的就少了;(F(i)是比 大的个数+1;变大的话,比大的就少了,F(i)就变小了)
所以需要操作次;
代码:
#include<iostream>
#include<algorithm>
#include<cmath>
#define int long long
using namespace std;
int c,n,k,s[500010],ans[500010];
struct node{int x,id;}a[500010];
bool cmp(const node &x,const node &y){
return x.x>y.x;
}
signed main()
{
cin>>c>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i].x;
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
//for(int i=1;i<=n;i++)cout<<a[i].x<<endl;
for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i].x; //前i项和
for(int i=1;i<=n;i++)
if(a[i].x!=a[i-1].x)
{ //f等于比ai大的个数+1
int now;
if(i>=k)now=a[k].x-a[i].x; //需要做的是将F减小;使F=K;
// 将 a[i].x+到= a[k].x,这样比他大的就k个了
else now=a[i].x*(k-i+1)-(s[k]-s[i-1]);//需要做的是将G增大;使G=K;
//需要 k-i+1项 (a[i].x~~~a[k].x) 都变成a[i].x +1
//将 (a[i].x~~~a[k].x)全看成等于 a[i].x然后再减去原来的数 (a[i].x~~~a[k].x)
//就是 a[i].x*(k-i+1)-(a[i].x~~~a[k].x);
// 也就是 a[i].x*(k-i+1)-(s[k]-s[i-1]);
for(int j=i;a[j].x==a[i].x;j++)ans[a[j].id]=now; //相同的一起处理
}
for(int i=1;i<=n;i++)cout<<ans[i]<<endl;
return 0;
}