zoukankan      html  css  js  c++  java
  • 【CF3709】 【PA2014】Bohater(贪心+思维)

    3709: [PA2014]Bohater

    Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special Judge
    Submit: 3178  Solved: 998
    [Submit][Status][Discuss]

    Description

    在一款电脑游戏中,你需要打败n只怪物(从1到n编号)。为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值。任何时候你的生命值都不能降到0(或0以下)。请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉

    Input

    第一行两个整数n,z(1<=n,z<=100000),分别表示怪物的数量和你的初始生命值。
    接下来n行,每行两个整数d[i],a[i](0<=d[i],a[i]<=100000)

    Output

    第一行为TAK(是)或NIE(否),表示是否存在这样的顺序。
    如果第一行为TAK,则第二行为空格隔开的1~n的排列,表示合法的顺序。如果答案有很多,你可以输出其中任意一个。

    Sample Input

    3 5
    3 1
    4 8
    8 3

    Sample Output

    TAK
    2 3 1
     

     

    应该都能想到分成两类处理+排序,但按什么排呢?

    我们把怪分成两种类型:回血怪和掉血怪考虑。回血怪按扣血升序排列即可。

    掉血怪的思路就比较妙比较好Van♂了,最后剩的血量是确定的,那么我们倒序推,则原来的扣血变成了“回血”,原来的回血变成了“扣血”,于是掉血怪也就相当于回血怪了,考虑按“扣血”升序排列,所以正序就是题给回血按降序排列。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<ctime>
    #include<cctype>
    #include<algorithm>
    #include<cstring>
    #include<iomanip>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<stack>
    #include<cmath>
    #include<bits/stdc++.h>
    #define ri register int
    #define ll long long
    #define For(i,l,r) for(ri i=l;i<=r;i++)
    #define Dfor(i,r,l) for(ri i=r;i>=l;i--)
    using namespace std;
    const int M=1e5+5;
    int n,t1,t2;
    ll s;
    struct node{
        int id,d,a;
    }a[M],b[M];
    inline ll read(){
        ll f=1,sum=0;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
        return f*sum;
    }
    inline bool cmp1(node x,node y){return x.d<y.d;}
    inline bool cmp2(node x,node y){return x.a>y.a;}
    int main(){
        n=read(),s=read();
        For(i,1,n){
            int x=read(),y=read();
            if(x<=y) a[++t1].d=x,a[t1].a=y,a[t1].id=i;
            else b[++t2].d=x,b[t2].a=y,b[t2].id=i;
        }
        sort(a+1,a+t1+1,cmp1);
        For(i,1,t1){
            if(s<=a[i].d){cout<<"NIE";return 0;}
            s=s-a[i].d+a[i].a;
        }
        sort(b+1,b+t2+1,cmp2);
        For(i,1,t2){
            if(s<=b[i].d){cout<<"NIE";return 0;}
            s=s-b[i].d+b[i].a;
        }
        cout<<"TAK"<<endl;
        For(i,1,t1) printf("%d ",a[i].id);
        For(i,1,t2) printf("%d ",b[i].id);
        return 0;
    }
  • 相关阅读:
    .NET深入解析LINQ框架(四:IQueryable、IQueryProvider接口详解)
    .NET简谈组件程序设计之(初识NetRemoting)
    .NET简谈组件程序设计之(delegate与event关系)
    .NET简谈组件程序设计之(上下文与同步域)
    .NET简谈特性(代码属性)
    .NET可逆框架设计
    使用KTM(内核事务管理器)进行文件事务处理
    .NET面向上下文、AOP架构模式(实现)
    .NET简谈设计模式之(装饰者模式)
    .NET对存储过程的调用抽象封装
  • 原文地址:https://www.cnblogs.com/jian-song/p/11773899.html
Copyright © 2011-2022 走看看