个人笔记:算法讲座4.1——画板

本文仅供参考学习使用,谢谢

问题描述:

Alice热爱绘画,圣诞节时Bob送了一块木板给她,作为她作品墙。以后Alice每画好一幅画,就用两个夹子夹在木板的上边缘欣赏。所有的画都是矩形的。且不会超出作品墙的范围。Bob也会经常来看看作品墙还剩余多少面积没有被覆盖。一旦剩余的面积少于原面积的1/2,Bob就要去买一块新的木板了。输入第一行a、b、N,表示木板的长(上边缘)、宽和作品数。从第二行开始,每行有三个整数,表示作品的位置和高度。

  • 输入:

每次查询的结论

  • 输出:

BUY(需要) NO(不需要)

思路分析:

画板的尺寸一定是从 0 cm开始到 N cm
所以 0~1cm 包含在画板内 N~N+1cm不包含在画板内 N cm是画板的最右端刻度,0 cm是画板的最左端刻度
Alice每次将新画的画挂在画板上时可能出现两种情况

  1. 直接覆盖在画板上
  2. 部分或整体覆盖在之前挂在画板上的画上,此时只需要考虑覆盖之前和覆盖之后的画哪一个高度更高即可

每输入一幅画的数据只需要考虑在当前画板上,每个单位长度上的值是否小于该画的高度,小于则输入,否则不改变
最后会得到画板上所有画覆盖完之后每个单位长度上的高度,没有覆盖就是0,覆盖了就是所覆盖的画中最高的那一个

算法描述:

  1. 需要一个int型的一维数组painting表示画板的上边缘长度。
    painting中的每一个数据都是当前单位长度上被覆盖的最大高度
  2. 一个F(a,b,v)函数对painting上的数据不断更新:
    a是当前输入的画的起始位置,b是当前输入的画的终止位置,v是当前输入的画的高度。需要一个if判断当前输入的画的高度是否大于当前画板上画的高度,只有大于才能覆盖
  3. 需要一个sum函数对画板上每一个单位长度的画的高度求和,并将求和结果与画板面积的一半(A*B/2)进行比较
    如果>=则输出BUY,<输出NO

测试数据:

  • 数据1:

100 20 4
15 42 7
20 80 15
86 90 20
18 70 3

  • 数据2:

1000 600 6
400 700 350
200 300 100
250 500 200
500 700 200
400 500 400
300 800 200

  • 结果1:

BUY

  • 结果2:

NO

代码

#include <stdio.h>
#define maxsize 1000000

int painting[maxsize]={0};

void create(int lchild, int rchild, int v){
    if (lchild==rchild) {
        if (painting[lchild]<v)
            painting[lchild]=v;
    } else {
        int mid=(lchild+rchild)/2;
        create(lchild, mid, v);
        create(mid+1, rchild, v);
    }
}

int sum(int A){
    int sum=0;
    for (int i=0; i<A; i++)
        sum+=painting[i];
    
    return sum;
}

int main(int argc, const char * argv[]) {
    int A=0,B=0,N=0;
    scanf("%d%d%d",&A,&B,&N);
    
    int a=0,b=0,v=0;
    for (int i=0; i<N; i++) {
        scanf("%d%d%d",&a,&b,&v);
        create(a, b-1, v);//如果输入b的话会将 b~b+1cm 也算入该画覆盖区
    }
    
//    int count=0;
//    for (int i=0; i<10; i++) {
//        for (int j=0; j<10; j++) {
//            printf("%2d",painting[count++]);
//        }
//        printf("\n");
//    }
    
    if (sum(A)>A*B/2) {//用的面积>画板的一半就要买,<=不用买
        printf("BUY\n");
    } else {
        printf("NO\n");
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值