[题解]Friendly Fire(Gym - 102215F)(贪心)

Friendly Fire

Nikita is a fan of Volvo Software games. Not so long ago this company has released a game too famous to be called.

Nikita’s opponent has n creatures, and the i-th of them has attack ai and has hi hit points. Nikita has a Friendly Fire spell. This spell is casted on two enemy creatures, and they simultaneously attack each other once. If the attacker’s attack is greater or equal than the target’s hit points, the target dies.

Help Nikita to choose two targets for Friendly Fire, so that the sum of attacks of all opponent’s creatures will become as small as possible.

Input
The first line contains an integer n (2≤n≤300000) — the number of the opponent’s creatures.

Each of the next n lines contains two integers ai and hi (1≤ai,hi≤109) — attack and hit points of the i-th creature.

Output
In the first line output a single integer — the maximal possible decrease of the total attack of the opponent’s creatures.

In the second line output two distinct integers from 1 to n — the numbers of creatures to cast the spell on.

If there are many possible answers, you may output any of them.

Examples
Input
3
4 3
3 1
5 4
Output
9
3 1
Input
2
1 2
4 8
Output
1
2 1
Input
2
1 2
1 2
Output
0
1 2

题意:大体的意思就是输入n头怪兽的攻击值和hp,两两格斗,求死去的怪兽最大的攻击值;

想法:我的想法是首先将怪兽按照攻击值大小进行排序,尽量选择攻击值高的怪兽去世,如果一个怪兽杀不死另一头怪兽,那么那只怪兽之后的怪兽都杀不掉那只怪兽(因为是按照攻击值由大到小排序的),这时指向这头怪兽的j++;有一个判定条件就是,如果它俩都互相杀死了对方,那么直接跳出循环,因为若继续向下找最优条件也不过是两个怪兽互相杀死,而如果继续向下,总攻击值是在不断变小的,不满足总攻击最大的条件。上个代码

#include <bits/stdc++.h>
#define io ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
using namespace std;
struct node {
    int a,h,id;
};node a[300009];
int cmp(const node &a,const node &b){
    return a.a>b.a;
}
int main()
{
    io
    int n,i,j;
    cin>>n;
    for(i=1;i<=n;++i){cin>>a[i].a>>a[i].h;a[i].id=i;}//记录id号;
    sort(a+1,a+1+n,cmp);//排序;
    ll loss=0;int x,y;
    i=1;j=2;
    while(i<=n||j<=n){//若i,j任一个大于n则跳出循环
            if(i==j)++j;//这里主要是判断i,j指向同一头怪兽的情况,j++;
        ll c1=a[i].h-a[j].a,c2=a[j].h-a[i].a;//两头怪兽是否去世;
        if(c1<=0&&c2<=0){
            if(a[i].a+a[j].a>=loss){loss=a[i].a+a[j].a;x=a[i].id;y=a[j].id;}
            break;
        }else if(c1>0&&c2>0){
            j++;
        }
        else if(c1<=0){
            if(a[i].a>=loss){loss=a[i].a;x=a[i].id;y=a[j].id;}
            j++;
        }else if(c2<=0){
            if(a[j].a>=loss){loss=a[j].a;x=a[i].id;y=a[j].id;}i++;
        }
    }
    cout<<loss<<endl;if(loss)cout<<x<<' '<<y<<endl;else cout<<1<<' '<<2<<endl;
    return 0;
}

经过这几次的test,感觉自己还是个小菜鸡,希望每次都能有所进步吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值