洛谷【P2003】平板

我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html

题目传送门:https://www.luogu.org/problemnew/show/P2003

我们先来灵性地怼一波出题人:

首先他在题目描述的第一段的最后一句话如是说道:“任意一平板的两端必需有支柱或者它在另一块平板上。”

意思就是如果某块板子搭在另一块板子上,那么就可以省去一个脚的柱子。

然后他在输入格式中如是说:“输入保证任意两块平板间没有重叠部分。”

然后我没仔细看题目描述,就以为不可能有板子重叠……所以我直接按高度排序在低于它的板子里找下面一块了……

然后狂\(Wa\)不止。不过机智如我,想到自己经常漏读题面然后就去反复读了几遍题面。

然后机房传出一声惨叫:

傻逼出题人傻逼出题人傻逼出题人

\(TM\)题面看错了!

所以正确做法是\(n^2\)暴力去找对于每一块板子高度小于等于当前板子并且可以支撑当前板子的某半部分的最高板子。把柱子高度累加起来就可以了。

时间复杂度:\(O(n^2)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

int n,ans;//n块板子,ans累计柱子高度

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}//快读

struct lines {
    int x1,x2,y;

    bool operator<(const lines &a)const {
        return y>a.y;
    }
}q[105];//存板子

int main() {
    n=read();
    for(int i=1;i<=n;i++)
        q[i].y=read(),q[i].x1=read(),q[i].x2=read();
    q[n+1].y=0,q[n+1].x1=0,q[++n].x2=10001;//加一块高度为0的极长的板子方便统计柱子到地上的柱子高度
    sort(q+1,q+n+1);//按高度排序
    for(int i=1;i<n;i++) {
        for(int j=1;j<=n;j++)
            if(q[j].y<=q[i].y&&i!=j)
                if(q[j].x1<=q[i].x1&&q[i].x1<q[j].x2) {
                    ans+=q[i].y-q[j].y;break;
                }//找左边的柱子落脚点,break是因为排过序后后面的板子显然不优
        for(int j=1;j<=n;j++)
            if(q[j].y<=q[i].y&&i!=j)
                if(q[j].x1<q[i].x2&&q[i].x2<=q[j].x2) {
                    ans+=q[i].y-q[j].y;break;
                }//找右边柱子落脚点
    }printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/AKMer/p/9634799.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值