D - Mike and distribution

D - Mike and distribution

題意:

​ 有兩個數列,個數相同,現在選出不超過n/2+1個數列下標,使得在每一個數列中下標的數字之和的二倍大於原數列,輸出答案和下標。

思路:

​ 題意是經過化簡 的,因爲題中並沒有說要選擇多少個下標,只是一個範圍,那麼最簡單的做法當然是選擇越多越好。

​ 方法:思考挑選的個數,明顯是大於數列個數的一半的。

​ 先對A數列做一次排序,那麼從大到小挑選的時候肯定滿足A數列,對於B數列,現選擇第一個數字,然後剩下的數字選則大的。若n是偶數,那麼再把最後一個數列選擇。

​ 其中有貪心的思想,巧妙。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;
typedef long long LL;

struct Node
{
    LL a,b;
    int pos;
}p[maxn];

int n;
int ans[maxn];

bool cmp(Node a,Node b)
{
    if(a.a == b.a)
        return a.b > b.b;
    return a.a > b.a;
}

int main()
{
    //freopen("in.txt","r",stdin);

    scanf("%d",&n);
    for(int i = 1;i <= n; i++) {
        scanf("%I64d",&p[i].a);
        p[i].pos = i;
    }
    for(int i = 1;i <= n; i++) {
        scanf("%I64d",&p[i].b);
    }
    sort(p+1,p+1+n,cmp);
    int pos = 1;
    int ansn = n/2+1;
    ans[1] = p[1].pos;
    for(int i = 2;i+1 <= n; i += 2) {
        if(p[i].b > p[i+1].b) ans[++pos] = p[i].pos;
        else ans[++pos] = p[i+1].pos;
    }
    if(!(n%2))
        ans[++pos] = p[n].pos;
    printf("%d\n",ansn);
    printf("%d",ans[1]);
    for(int i = 2;i <= ansn; i++) {
        printf(" %d",ans[i]);
    }
    printf("\n");
    return 0;
}
發佈了365 篇原創文章 · 獲贊 14 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章