2018全国多校算法寒假训练赛(第一周) A.B

6 篇文章 0 订阅
1 篇文章 0 订阅

分开来写。不然太长了看的不舒服,这是AB两题的- -
A.大吉大利,今晚吃鸡——枪械篇
链接:https://www.nowcoder.com/acm/contest/67/A
来源:牛客网

题目描述
在绝地求生(吃鸡)游戏里,不同的枪支有不同的威力,更是可以搭配不同的配件,以提升枪支的性能。 每一把枪都有其威力及其可装备配件种类。每一个配件有其所属种类,可以为枪支提供威力的百分比加成。每一把枪只能装备一个同类配件。给你n把枪支和m个配件,枪的威力为p,可装备的配件数量为k,为k个不同类型的配件,同种类配件只可以装备一个。配件种类用数字q表示,配件威力加成用一个小数b表示。请你挑选一把枪并为其搭配配件使其威力最大。
假设一把枪的威力是p,装配的k个配件的威力加成是bi,那么枪最后的威力w=p*(1+b1+b2+…+bk)。

输入描述:
数据有多组,处理到文件结束。
第一行两个整数n和m,代表枪支数量和配件数量。
接下来n行,描述n把枪的属性:第一个整数为p,代表枪支的威力;第二个整数为k,代表该枪支可装备的配件数量;后面k个整数,代表可装备配件的种类。
接下来m行,描述m个配件的属性:第一个整数为q,代表配件的种类,第二个浮点数为b,代表配件可以为枪支提供的威力加成。
输出描述:
每组数据输出为一行,输出一个浮点数,代表合理装备配件后的枪支最大威力。精确到小数点后4位。
示例1
输入

3 6
120 3 1 2 3
100 4 1 2 3 4
110 3 2 3 4
1 0.12
2 0.23
2 0.26
4 0.57
3 0.35
5 0.41
输出

239.8000
说明

对于上面的样例,正确答案应该是,使用第三把枪,配上第三、四、五个配件。
枪的最终威力就是110*(1+0.26+0.57+0.35)=239.8
备注:
对于100%的数据,
1 <= n,m,k,q <= 1000;
0 <= p <= 1000;
0 <= b <= 1。

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1  
#define PI 3.1415926 
using namespace std ;
typedef long long ll;
typedef unsigned long long ull;
const ll _max = 2000;
struct gun{
    double p,k;
    int a[_max];
}g[_max];
double z[_max];
double w[_max];
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        memset(z,0,sizeof(z));
        for(int i = 1 ; i <= n ; i++){
            scanf("%lf%lf",&g[i].p,&g[i].k);
            for(int j = 1 ; j <= g[i].k ; j++)
                scanf("%d",&g[i].a[j]);
        }
        for(int i = 1 ; i <= m ; i++){
            int num;
            double ch;
            scanf("%d%lf",&num,&ch);
            z[num] = max(z[num],ch);
        }
        double cnt;
        double w_max = 0;
        for(int i = 1 ; i <= n ; i++){
            cnt = 1.0;
            for(int j = 1 ; j <= g[i].k ; j++){
                cnt += z[g[i].a[j]];
            }
            w[i] = g[i].p*cnt;
            w_max = max(w_max,w[i]);
        }
        printf("%.4lf\n",w_max);
    } 
    return 0;
}
/*
3 6
120 3 1 2 3
100 4 1 2 3 4
110 1 5
1 0.12
2 0.23
2 0.26
4 0.57
3 0.35
5 0.41
*/

题目很简单,输入配件的时候把同一配件挑选最大的就行了。然后类型要用double,别用float。因为精度问题。最初用float一直卡wa。

B.最强的决斗者一切都是必然的!
链接:https://www.nowcoder.com/acm/contest/67/B
来源:牛客网

题目描述
L一直喜欢玩游戏王这款声控印卡游戏,使用一套连锁式削血卡组便可战无不胜。每当陷入危机即将败北之际,L便会高呼“最强的决斗者一切都是必然的!”,然后发动闪光印卡技能,直接翻盘,伤害不多不少,正好足够击败对手。
发动闪光印卡技能后,L抽取一张牌,然后微微一笑。接着L以一定顺序打出若干张牌,造成的伤害正好等于对方的生命值。每一张牌都有其发动速度以及效果。如果后发动的一张牌的发动速度不小于前一张牌,则后发动的那张牌会在前一张牌后进行连锁发动,这张牌的连锁数就是连锁发动的编号。不进行连锁发动的牌,连锁数为1。同一连锁中的牌,后发动的牌先生效。
如下图,5张牌的速度分别为(1,2,2,2,3),因此它们进行连锁发动。连锁数分别为(1,2,3,4,5),因为连锁中的牌,后发动的先生效,所以,生效顺序为(5,4,3,2,1)。
为简化问题,我们假设发动的牌的效果有如下几种:
1. 对对方造成X点伤害
2. 对对方造成这张牌的连锁数乘X点的伤害
3. 同一连锁中的牌全部无效
4. 连锁中的前一张牌无效
现在你知道L发动牌的效果、速度和顺序,求L能对对方造成多少伤害。
输入描述:
数据有多组,处理到文件结束
第一行一个整数n,代表L发动了多少张牌。
接下来n行,前两个数是两个整数s和t,代表牌的发动速度和效果(数字对应上述4类效果)。如果是第1、2类效果,则紧接着一个整数x,代表效果中的X的数值。
输出描述:
每组数据输出一行,一个整数,代表L能对对方造成的伤害。
示例1
输入

9
1 1 300
2 2 400
2 3
2 2 500
1 1 1000
3 4
2 1 600
3 3
3 4
输出

2600
说明

一共发动了9张牌,前四张为一次连锁发动,第四张先生效,连锁数为4,造成4*500伤害。接着第三张牌生效,使第一二张牌无效。第五六张牌为一次连锁发动,第六张牌先生效,使其连锁的前一张牌,即第五张牌无效。第七八九张牌为一次连锁发动,第九张牌先生效,使连锁中的前一张牌,即第八张牌无效。接着第七张牌生效,造成600伤害。
总伤害为4*500+600=2600伤害。
备注:
对于100%的数据,
1 <= n,x <= 1000;
1 <= s <= 3;
1 <= t <= 4。

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1  
#define PI 3.1415926 
using namespace std ;
typedef long long ll;
typedef unsigned long long ull;
const ll _max =1000+50;
struct node{
    int s,t;
    int x;
}card[_max];
int main(){
    int n;
    while(~scanf("%d",&n)){
        int id = 0;
        card[id].s=-1;
        int ans = 0;
        while(n--){
            int s,t,x;
            scanf("%d%d",&s,&t);
            if(t<=2) scanf("%d",&x);
            else x = 0;
            if(s < card[id].s){
                for(int i = id ; i >= 1 ; i--){
                    int c = card[i].t;
                    if(c==1) ans+=card[i].x;
                    else if(c==2) ans+=card[i].x*i;
                    else if(c==3) break;
                    else i--;
                }
                id = 0;
            }
            card[++id].s=s;
            card[id].t=t;
            card[id].x=x;
        }
        for(int i = id ; i >= 1 ; i--){
            int c = card[i].t;
            if(c==1) ans+=card[i].x;
            else if(c==2) ans+=card[i].x*i;
            else if(c==3) break;
            else i--;
        }
        printf("%d\n",ans);
    }
}/*
9
1 1 300
2 2 400
2 3
2 2 500
1 1 1000
3 4
2 1 600
3 3
3 4
*/

一边输入一边模拟栈,当速度小于前一速度就全部出栈,并且按照顺序进行使用卡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值