洛谷 P5661 题解

题目传送门

思路:

每乘坐一次地铁,就产生一张优惠券,等面值, 45 45 45 分钟内使
用有效。

每次乘坐公交车时,先回看下是否有优惠券用,搜索所得所有的优惠券。

优惠券是否能用依赖于:1. 面值 2. 时间 3.这张是否已用过。

//优惠券信息
struct coupon
{ int price ;
int time ;
bool use ;
};

优惠券可产生多个,用数组存放。

ticket_free ticket [ N ] ; // 优惠券,最多n个

对于第 i i i 次乘车:

若乘坐地铁:则会产生优惠券并直接计费。

若乘坐公交车: 则先查找是否有优惠券用,有则用,无优惠券用,直接计费。

以上过程可以边输入边处理。

Coding Time \text{Coding Time} Coding Time

#include <iostream>
using namespace std;
#define N 100000
int ans , n , x , m ;//x为当前得到的优惠券的编号,n此旅行,可用的优惠券从m编号

struct ticket_free
{ 
    int price;
    int ti ;
    bool use ;
}ticket [N];

int main ( )
{ 
    cin >> n ;
    int j,bus,price,t;
    for ( int i = 0; i < n ; i ++ )
    { 
        cin >> bus >> price >> t;
        if( bus == 0 ) //本次乘坐地铁,产生优惠券
        { 
            ticket[x].price = price;
            ticket[x].ti = t;
            ticket[x].use = true;
            ans += price ;
            x++;
            continue ;
        }
        //本次乘坐公交车,查看是否有能使用的优惠券
        for ( j = m ; j < x ; j ++ )
        { 
            if( ticket[j].ti + 45< t )// 此处为关键点,淘汰超时的车票
            { 
                m = j;
                continue;
            }
            if ( ticket[j].use )
            { 
                if ( ticket [j].price >= price )
                { 
                    ticket[j].use = false;
                    break ;
                }
            }
        }
        if (j == x)
        {
            ans += price ; 
        }
    }
    cout << ans ;
    return 0;
}

本题易踩的坑点:

若直接暴搜会 TLE \text{TLE} TLE

用暴搜剪枝:实际上每次查询是否有可用优惠券时,最多有 45 45 45 张,
这样时间复杂度为 45 ∗ 1000000 45*1000000 451000000 ,可以提高算法效率。

AC记录

如有疑问,欢迎私信。

若有不对,请指出。

posted @ 2022-07-16 10:09  Andy__L  阅读(26)  评论(0)    收藏  举报