2013ACM多校联合(1)_CSUST_拯救猫咪

Description

菱菱平时生活非常勤俭,从来只吃外卖不吃食堂。某日,好心的菱菱收养了一只流浪猫,但是猫咪对菱菱糟糕的伙食状况非常不满,屡次想要偷吃菱菱的鸟改善生活。于是菱菱想到放猫咪去食堂蹭饭,但是去食堂的路上有许多凶悍的野狗巡逻把守,直接去恐怕有来无回,当然这也难不倒聪明的菱菱,菱菱给猫咪做了一个外面画着老虎的盒子。这样猫咪可以在野狗经过的时候趴下休息,用盒子把自己保护起来。待危险解除后继续前行。同时由于经过了充分的休息,可以获得一定的能量点数,猫咪可以选择进行一次长达数米的跳跃。现在菱菱想知道猫咪最少需要多长时间可以到达食堂。

开始时,猫咪在坐标 0 点出发,初始能量为 0 ,食堂的坐标为 D 米,猫咪的前进速度为 1 米/秒。每一秒,猫咪可以选择原地休息(能量点加1)或前进 1 米或进行一次跳跃(前进 K 米,消耗 K−1 点能量,当然前提是当前拥有至少 K−1 点能量)。每一只野狗也在开始时同时出现,其属性包括出现时的坐标,前进速度,视野范围(可以同时向前和向后看)。每只野狗的前进方向都是坐标轴负方向。猫咪必须完全在狗的视野范围之外才能行动。

注意,判断在 x 位置的猫,前进 t 米,是否会被位置为 y ,速度为 a ,视野为 b 的狗发现的依据是[x; x + t]与[y−a−b; y + b] 的交是否为空集。

Input

测试文件包含多组数据。

每组数据第一行有两个整数分别表示食堂的位置D(1D10000) 野狗的个数n(0n2,000)

接下来有n 行,每行有三个整数,表示一只野狗的出现位置,前进速度,视野范围。保证野狗出现的位置小于2D。文件以一行两个 -1 表示结束。

Output

对于每组数据,输出一个整数t,表示猫咪到达食堂的时间。

Sample Input

10 3
18 2 1
3 2 1
8 1 2

-1 -1

Sample Output

11

稍作分析:
简单题,但这道题当时我没有想出来,甚至考试结束看过解题依旧没有通过...最后还是经学长指点才勉强通过,由此可见....。
引用解题上的方法,这道题单纯模拟即可,能跳则跳。个人感觉时间卡的蛮紧,注意:已经路过的野狗及时要删掉,之后无需判断;
猫咪能够前行的最大距离为min(该点离最近的野狗视线前沿-1,魔力值+1,离食堂的距离),如果该点离最近的野狗视线前沿-1
为非正数,必须原地休整。

上代码:

 1 #include <cstdio>
 2 #include <malloc.h>
 3 #define min(a,b) (a<b)?a:b
 4 #define INF 0x3f3f3f3f
 5 #define len (struct obj*)malloc(sizeof(struct obj)) 
 6 struct obj{    
 7     int y,a,b;    
 8     struct obj*next;
 9 }; 
10 int main(){
11     int i,d,n,x,m,b,time;
12     struct obj*head;
13     struct obj*til;
14     struct obj*tp;
15     struct obj*p;
16     while(scanf("%d %d",&d,&n)!=EOF&&(d!=-1||n!=-1)){
17         head=len;
18         til=head;
19         til->next=NULL;
20         for (i=1;i<=n;i++){
21             til->next=len;
22             til=til->next;
23             til->next=NULL;
24             scanf("%d %d %d",&til->y,&til->a,&til->b);
25         }
26         x=m=time=0;
27         while(x<d){
28             tp=head;
29             while(tp->next!=NULL){
30                 if (x>tp->next->y+tp->next->b){
31                     p=tp->next->next;
32                     free(tp->next);
33                     tp->next=p;
34                 }
35                 else tp=tp->next;
36             }
37             tp=head->next;
38             b=INF;
39             while(tp!=NULL){
40                 b=min(b,tp->y-tp->b-tp->a-x);
41                 tp=tp->next;
42             }
43             b--;
44             b=min(b,d-x);
45             if (b<0)b=0;
46             b=min(b,m+1);
47             m+=(-b+1);
48             x+=b;
49             tp=head->next;
50             while(tp!=NULL){
51                 tp->y-=tp->a;
52                 tp=tp->next;
53             }
54             time++;
55         }
56         printf("%d\n",time);
57     }
58     return 0;
59 }

 

转载于:https://www.cnblogs.com/shellbase/archive/2013/04/10/3012405.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值