本文仅供参考学习使用,谢谢
问题描述:
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每次将新画的画挂在画板上时可能出现两种情况
- 直接覆盖在画板上
- 部分或整体覆盖在之前挂在画板上的画上,此时只需要考虑覆盖之前和覆盖之后的画哪一个高度更高即可
每输入一幅画的数据只需要考虑在当前画板上,每个单位长度上的值是否小于该画的高度,小于则输入,否则不改变
最后会得到画板上所有画覆盖完之后每个单位长度上的高度,没有覆盖就是0,覆盖了就是所覆盖的画中最高的那一个
算法描述:
- 需要一个int型的一维数组painting表示画板的上边缘长度。
painting中的每一个数据都是当前单位长度上被覆盖的最大高度 - 一个F(a,b,v)函数对painting上的数据不断更新:
a是当前输入的画的起始位置,b是当前输入的画的终止位置,v是当前输入的画的高度。需要一个if判断当前输入的画的高度是否大于当前画板上画的高度,只有大于才能覆盖 - 需要一个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;
}