学习随笔——codeforces题目Monsters And Spells解答

今天在codeforce刷到了一道C题,感觉还很有意思,主要用到了贪心算法。

该题原地址如下https://codeforces.com/problemset/problem/1626/C

题目截图如下:

 

关键词:二分查找,动态规划,贪心算法,*1700

简要翻译:你正在玩一款魔法类游戏,你需要击倒你遇到的每一个怪物,你的攻击充能机制如下:你可在任意时刻进行攻击,但如果你在该时刻前一秒未攻击,你的攻击力只有1,攻击力会随着你持续攻击而升高,同时会耗费与攻击力等量的能量。例如你在第x秒攻击第一次,攻击力为1,耗费1点能量;在第x+1秒攻击第二次,攻击力加1,变为2,,耗费2点能量,以此类推。现在给出怪物出现时间与血量的一 一对应序列,要求在怪物出现时必须将其打倒,想要将怪物打倒攻击力应大于等于怪物的血量。最后统计整个过程耗费的总能量。我们在本题要求该值达到最小。

上来的思路一般是从前往后遍历,但会出现之前充能足够但之后充能不够的情况。我在这里的方法是区间法:构造一个二元组(a,b),a为起始时间坐标,b为怪物出现时间坐标,b-a为你打倒该怪物需要的充能时间。每个怪物都对应着一个充能区间,区间之间会出现覆盖情况。如果出现这种情况,说明两段充能时间不是独立的,起始时间坐标应该更新为两二元组中较小的起始时间坐标;未出现该情况说明独立,可不更新。本质还是贪心算法。

代码如下:

复制代码
 1 /*解决方法:区间覆盖法
 2 设置一个结构体存储头部坐标与尾部坐标,实现区间的合并 
 3 */ 
 4 #include <stdio.h>
 5 #include <malloc.h>
 6 long long int max (long long int a,long long int b)
 7 {
 8     if (a>b)
 9         return a;
10     else
11         return b;
12 }
13 typedef struct n
14 {
15     long long int start;
16     long long int end;
17 }n;
18 long long int creat_main (long long int num)
19 {
20     long long int point=0;
21     const long long int num1=num;
22     long long int start1=0;
23     n *n1=(n *)malloc(sizeof(n)*num);
24     for (long long int i=0;i<num;i++)
25         scanf("%lld",&n1[i].end);
26     for (long long int i=0;i<num;i++)
27     {
28         scanf("%lld",&start1);
29         n1[i].start=n1[i].end-start1;
30     }
31     for (long long int i=0;i<num1;i++)
32     {
33         for (long long int j=0;j<num1;j++)
34         {
35             if (n1[j].start>=n1[i].start&&n1[j].start<n1[i].end)
36                 n1[j].start=n1[i].start;
37         }
38     }
39     long long int final_end=n1[0].end;
40     long long int k0=0;
41     for (long long int i=0;i<num1;i++)
42     {
43         if (num1==1)
44         {
45             point+=(n1[0].end-n1[0].start+1)*(n1[0].end-n1[0].start)/2;
46             break;
47         }
48         if (i==num1-1)
49         {
50             point+=(n1[num1-1].end-n1[num1-1].start+1)*(n1[num1-1].end-n1[num1-1].start)/2;
51             break;
52         }
53         if (n1[i].start==n1[i+1].start)
54         {
55             final_end=max(n1[i].end,n1[i+1].end);
56             continue;
57         }
58         else
59         {
60             point+=(final_end-n1[i].start+1)*(final_end-n1[i].start)/2;
61             final_end=n1[i+1].end;
62         }
63     }
64     return point;
65 }
66 int main (int argc,char *argv[])
67 {
68     long long int type=0;//次数
69     long long int num=0;//数量
70     long long int point=0; 
71     scanf("%lld",&type);
72     const long long int num1=type;
73     long long int *end=(long long int *)malloc(sizeof(long long int)*num1);
74     for (long long int i=0;i<type;i++)
75     {
76         scanf("%lld",&num);
77         point=creat_main(num);
78         end[i]=point;
79     }
80     for (long long int i=0;i<type;i++)
81         printf("%lld\n",end[i]);
82     return 0;
83 }
复制代码
posted @   Johnson-Hugo  阅读(114)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示