【CF1114】【贪心(排序)】Yet Another Array Partitioning Task

Yet Another Array Partitioning Task

【题意】:

题目意思是:给你n个数,让你分开为k组,每一组必须不小于m,然后每一组挑选出m个数,每一组数求和得到的结果输出,并且输出对应的分界点。

【题解】:

自己的做法:

其实很容易观察就得出一个小结论,就是:无论你怎么分都好,必定会把排序后前m*k大的数给挑选出来。这个结论虽然说死了,但是你只能从这一个突破口出发才能做题,大家不如动手写一下事例,必定会把最大的那几个数给依次挑出来的。好的,然后大家就会发现,只要把对应的都拿好了,其他的只要分组即可。就是说:我把全部前m*k大的数字给标记了,然后以他们为依据来划分,只要一组里面有m个,那么就输出分界点。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
typedef long long ll;
typedef struct Node{
    int Ind,No,x;
}Node;
int cmp1(Node s,Node t){
    if(s.x==t.x) return s.Ind<t.Ind;
    return s.x<t.x;
}
int cmp2(Node s,Node t){
    return s.Ind<t.Ind;
}
int main()
{
    int n,m,k;
    ll sum=0;
    Node a[N];
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].x);
        a[i].Ind=i;
    }
    sort(a+1,a+1+n,cmp1);
    for(int i=1;i<=n;i++){
        a[i].No=i;
        if(i>n-m*k){
            sum+=a[i].x;
        }
    }
    printf("%lld\n",sum);
    sort(a+1,a+1+n,cmp2);
    int cnt=0,tot=0;
    for(int i=1;i<n;i++){
        if(n-m*k<a[i].No&&cnt<m){
            cnt++;
        }
        if(cnt==m){
            cnt=0;
            tot++;
            if(tot<k)
                printf("%d ",i);
        }
    }
    return 0;
}
/*
17 1 4
40654398 -73772996 -301750550 47084378 
-989570362 26931632 -630673783 889561285 
-392590161 977684923 -409889397 -706593539 
636930801 546359196 317700410 90744216 -636840634
*/

后来看到了别人官方的题解,才知道什么叫做“差距”。

思路清晰,写得还真不错。

首先它把前m*k个数挑出来,然后记录对应的下标,因为我们是挑出来的过程中只关注是否为前m*k个,然后我们还需要排序一下,让对应的下标有条不紊,然后直接输出k-1组,每一组就是对应m个为一组。

贴上代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(NULL);

    int n,m,k;
    cin>>n>>m>>k;

    vector <pii> a(n);
    vector <int> ind(m*k);
    for(int i=0;i<n;i++){
        cin>>a[i].first;
        a[i].second=i;
    }
    sort(a.begin(),a.end(),greater<pii>() );
    //sort(a.begin(),a.end(),[](pii s,pii t){return s.first>t.first;});
    ll sum=0;
    for(int i=0;i<m*k;i++){
        sum+=a[i].first;
        ind[i]=a[i].second;
    }

    sort(ind.begin(),ind.end());

    cout<<sum<<endl;
    for(int i=0;i<k-1;i++){
        cout<<ind[(i+1)*m-1]+1<<" ";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/87206327