POJ 2454 Jersey Politics 解题报告(随机化)

    题目大意:给定3*k个数字,分为3组,至少让两组中数字的和大于500*k。

    解题报告:随机化算法。首先可以排序,让和最小的数字分为一组,即使另外两组的和必须大于500k。

    然后就随机交换两组的数字。当满足要求时打印顺序即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <ctime>
using namespace std;

struct Node
{
    int index;
    int val;
    bool operator<(const Node& cmp) const
    {
        return val<cmp.val;
    }
} node[180];

int main()
{
    srand((unsigned)time(0));

    int k;
    scanf("%d",&k);

    int n=k*3;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&node[i].val);
        node[i].index=i;
    }

    sort(node,node+n);

    int UP=k*500;
    int k2=k*2;

    int sum1=0,sum2=0;
    for(int i=k;i<k2;i++)
        sum1+=node[i].val;
    for(int i=k2;i<n;i++)
        sum2+=node[i].val;

    while(sum1<=UP || sum2<=UP)
    {
        int p=rand()%k+k;
        int q=rand()%k+k2;

        int sub=node[p].val-node[q].val;
        sum1-=sub;
        sum2+=sub;
        swap(node[p],node[q]);
    }

    for(int i=0;i<n;i++)
        printf("%d\n",node[i].index+1);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值