【codeforces 798D】Mike and distribution

【题目链接】:http://codeforces.com/contest/798/problem/D

【题意】

让你选一个下标集合
p1,p2,p3..pk
使得2*(a[p1]+a[p2]+..+a[pk])>∑ai
同时2*(b[p1]+b[p2]+..+b[pk])>∑bi

【题解】

两个式子都可以转化为
a[p1]+a[p2]+..+a[pk]>剩余的元素
(移项就能得到)
接着用构造的方法搞;
首先把A数组降序排;
(排的时候要记录每个元素它原来的下标)
即a[i].val和a[i].id
然后把a[1].id加入答案;
对于剩下的n-1个
顺序成对地处理

对于a[i]和a[i+1]
看看b[a[i].id]和b[a[i+1].id]哪一个大;
哪一个大
就把相应的id加入到答案序列中;
因为a是降序排的;
且已经把一个最大的a放在了头位置;
这就能保证对于每一个ai都有一个比他小的ai;
而我们每次成对地把b大的加入答案;
也能保证每一个bi都有一个比他小的bi;
很棒的思路吧

【Number Of WA

0

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100;

struct abc
{
    int val,id;
};

int n,b[N];
abc a[N];
vector <int> ans;

bool cmp1(abc a,abc b)
{
    return a.val > b.val;
}

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
    cin >> n;
    rep1(i,1,n)
        cin >> a[i].val,a[i].id = i;
    rep1(i,1,n)
        cin >> b[i];
    sort(a+1,a+1+n,cmp1);
    ans.pb(a[1].id);
    for (int i = 2;i <= n;i+=2)
    {
        int po = a[i].id;
        if (i+1<=n && b[a[i+1].id]>b[po])
            po = a[i+1].id;
        ans.pb(po);
    }
    int len = ans.size();
    cout << len << endl;
    rep1(i,0,len-1)
        cout << ans[i] <<' ';
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(119)  评论(0)    收藏  举报