趣味编程题之Blocked Billboard

During long milking sessions, Bessie the cow likes to stare out the window of her barn at two huge rectangular billboards across the street advertising “Farmer Alex’s Amazingly Appetizing Alfalfa” and “Farmer Greg’s Great Grain”. Pictures of these two cow feed products on the billboards look much tastier to Bessie than the grass from her farm.
One day, as Bessie is staring out the window, she is alarmed to see a huge rectangular truck parking across the street. The side of the truck has an advertisement for “Farmer Smith’s Superb Steaks”, which Bessie doesn’t quite understand, but she is mostly concerned about the truck potentially blocking the view of her two favorite billboards.

Given the locations of the two billboards and the location of the truck, please calculate the total combined area of both billboards that is still visible. It is possible that the truck obscures neither, both, or only one of the billboards.
在长时间的挤奶环节,Bessie喜欢盯着她谷仓窗口的两个巨大的长方形的广告牌,该街头广告牌上书:“农夫亚历克斯好吃的香苜蓿”和“农民格雷戈的大量粮食”。广告牌上的这两种奶牛饲料产品看起来比Bessie她自己农场的草料味道更好。
有一天,当Bessie正盯着窗外时,她惊恐地看到一辆巨大的长方形卡车停在街对面。卡车的一侧有一个广告,上书:“农场主史密斯的超级牛排”,Bessie对此并不十分了解,但她最担心的是卡车可能挡住了她最喜欢的两个广告牌的视野。
考虑到两个广告牌的位置和卡车的位置,请计算仍然可见的两个广告牌的剩余总面积。对于两个广告牌,卡车可能一个都不遮盖,也可能都遮盖,也可能只遮盖一个。

INPUT FORMAT (file billboard.in):

The first line of input contains four space-separated integers: x1x1 y1y1 x2x2 y2y2, where (x1,y1)(x1,y1) and (x2,y2)(x2,y2) are the coordinates of the lower-left and upper-right corners of the first billboard in Bessie’s 2D field of view. The next line contains four more integers, similarly specifying the lower-left and upper-right corners of the second billboard. The third and final line of input contains four integers specifying the lower-left and upper-right corners of the truck. All coordinates are in the range -1000 to +1000. The two billboards are guaranteed not to have any positive area of overlap between themselves.

输入的第一行包含四个整数:x1、 y1, X2、 y2,从Bessie的二维视角来看,(x1,y1)(x2,y2)是分别是第一个广告牌的左下,右上坐标。下一行包含四个整数,同样地指明为第二个广告牌的左下和右上坐标。输入的第三行也即最后一行同样包含四个整数,它们指明的是卡车的左下和右上坐标。所有坐标值都在 -1000到1000的范围内。两个广告牌保证不会有任何重叠区域。

OUTPUT FORMAT (file billboard.out):

Please output the total combined area of both billboards that remains visible.
请输出仍然可见的两个广告牌的剩余总面积

SAMPLE INPUT:

1 2 3 5
6 0 10 4
2 1 8 3
SAMPLE OUTPUT:

17
Here, 5 units of area from the first billboard and 12 units of area from the second billboard remain visible.
这里,第一个广告牌有5单位的面积可视,第二个有12单位,共计17单位
Problem credits: Brian Dean

解析:

矩形1左下坐标 (left1, bottom1),右上(right1, top1)
矩形2左下坐标 (left2, bottom2),右上(right2, top2)
横坐标重叠长度overlapX = (right1-left1)+(right2-left2) - [max(right1,right2) - min(left1,left2)]
纵坐标重叠长度overlapY=(top1-bottom1)+(top2-bottom2) - [max(top1,top2) - min(bottom1,bottom2)]
重叠长度为负数时面积为0
重叠面积overlapS=overlapX*overlapY

答案:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;

import java.lang.Math;
public class BlockedBillboard1 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("billboard.in"));
        PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("billboard.out")));
        int[][] rectangle = new int[3][4];
        int left, bottom, right, top;
        left = 0;
        bottom = 0;
        right = 0;
        top = 0;
        for (int i = 0; i < 3; ++i) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            left = Integer.parseInt(st.nextToken());
            rectangle[i][0]= left;
            bottom = Integer.parseInt(st.nextToken());
            rectangle[i][1]= bottom;
            right = Integer.parseInt(st.nextToken());
            rectangle[i][2]= right;
            top = Integer.parseInt(st.nextToken());

            rectangle[i][3]= top;
        }
        int overlapX, overlapY, overlapX2, overlapY2, sumOverLap, sumAllLap;
        overlapX = 0;
        overlapY = 0;
        overlapX2 = 0;
        overlapY2 = 0;
        sumOverLap = 0;
        sumAllLap = 0;
        overlapX = (rectangle[0][2]-rectangle[0][0])+(rectangle[2][2]-rectangle[2][0]) - (Math.max(rectangle[0][2],rectangle[2][2]) - Math.min(rectangle[0][0],rectangle[2][0]));
        overlapY = (rectangle[0][3]-rectangle[0][1])+(rectangle[2][3]-rectangle[2][1]) - (Math.max(rectangle[0][3],rectangle[2][3]) - Math.min(rectangle[0][1],rectangle[2][1]));
        overlapX = zero(overlapX);
        overlapY = zero(overlapY);
        overlapX2 = (rectangle[1][2]-rectangle[1][0])+(rectangle[2][2]-rectangle[2][0]) - (Math.max(rectangle[1][2],rectangle[2][2]) - Math.min(rectangle[1][0],rectangle[2][0]));
        overlapY2 = (rectangle[1][3]-rectangle[1][1])+(rectangle[2][3]-rectangle[2][1]) - (Math.max(rectangle[1][3],rectangle[2][3]) - Math.min(rectangle[1][1],rectangle[2][1]));
        overlapX2 = zero(overlapX2);
        overlapY2 = zero(overlapY2);
        sumOverLap = overlapX*overlapY + overlapX2*overlapY2;
        sumAllLap = (rectangle[0][2] - rectangle[0][0])*(rectangle[0][3] - rectangle[0][1]) + (rectangle[1][2] - rectangle[1][0])*(rectangle[1][3] - rectangle[1][1]);

        pw.println(sumAllLap - sumOverLap);
        br.close();
        pw.close();
    }
    private static int zero(int i) {
        if(i<0){
            return 0;
        }
        return i;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`blocked_range`是一个C++标准库中的类,用于表示一个范围(range)被拆分成若干个块(blocks)。它通常用于并行算法中,将一个大任务分割成若干个小任务,并行处理这些小任务以提高执行效率。 `blocked_range`的定义如下: ```c++ template<typename Value> class blocked_range { public: blocked_range(Value begin, Value end, size_t grainsize = 1); Value begin() const; Value end() const; size_t size() const; bool empty() const; }; ``` 其中`begin`和`end`表示范围的起始和结束位置,`size`表示范围的大小,`empty`表示范围是否为空。`grainsize`表示每个块的大小,如果未指定,默认为1。 在并行算法中,我们通常需要将一个范围分成若干个块,并行处理这些块。`blocked_range`可以很方便地将一个范围拆分成若干个块,如下所示: ```c++ void parallel_process(blocked_range<int>& range) { if (range.empty()) return; if (range.size() <= range.grainsize()) { process_range(range.begin(), range.end()); // 处理完整个范围 } else { // 将范围分成若干个块,分别处理每个块 int mid = range.begin() + range.size() / 2; parallel_process(blocked_range<int>(range.begin(), mid, range.grainsize())); parallel_process(blocked_range<int>(mid, range.end(), range.grainsize())); } } ``` 在上面的代码中,`parallel_process`函数接受一个`blocked_range`对象作为参数,如果该范围为空,则直接返回;否则,如果该范围的大小小于等于指定的块大小(`grainsize`),则直接处理该范围;否则,将该范围分成两个子范围,并递归地调用`parallel_process`函数处理这两个子范围。这样,我们就可以很方便地将一个范围分成若干个块,并行处理这些块。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值