This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/3_Bronze/Rect_Geo.md
2020-06-17 16:10:45 -07:00

4.5 KiB

id title author
rect-geo Rectangle Geometry Darren Yao, Michael Cao

"Geometry" problems on USACO Bronze are usually quite simple and limited to intersections and unions of squares or rectangles.

  • Some only include two or three squares or rectangles, in which case you can simply draw out cases on paper. This should logically lead to a solution.
  • Also, the coordinates typically only go up to 1000, so a program that performs \approx 1000^2 operations (ex. with a nested loop) should pass.

Rectangle Class (Java)

A useful class in Java for dealing with rectangle geometry problems is the built-in Rectangle class. To create a new rectangle, use the following constructor:

//creates a rectangle with upper-left corner at (x,y) with a specified width and height
Rectangle newRect = new Rectangle(x, y, width, height); 

The Rectangle class supports numerous useful methods.

firstRect.intersects(secondRect) checks if two rectangles intersect.

firstRect.union(secondRect) returns a rectangle representing the union of two rectangles.

firstRect.contains(x, y) checks whether the integer point (x,y) exists in firstRect.

firstRect.intersection(secondRect) returns a rectangle representing the intersection of two rectangles.

This class can often lessen the implementation needed in a lot of bronze problems and CodeForces problems.

For example, here is a nice implementation of the problem Blocked Billboard (editorial).

import java.awt.Rectangle; //needed to use Rectangle class
import java.io.*;
import java.util.*;

public class blockedBillboard{
    public static void main(String[] args) throws IOException{
        Scanner sc = new Scanner(new File("billboard.in"));
        PrintWriter pw = new PrintWriter(new FileWriter("billboard.out"));
        int x1, y1, x2, y2;

        //the top left point is (0,0), so you need to do -y2

        x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
        Rectangle firstRect = new Rectangle(x1, -y2, x2-x1, y2-y1);

        x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
        Rectangle secondRect = new Rectangle(x1, -y2, x2-x1, y2-y1);

        x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
        Rectangle truck = new Rectangle(x1, -y2, x2-x1, y2-y1);

        long firstIntersect = getArea(firstRect.intersection(truck));
        long secondIntersect = getArea(secondRect.intersection(truck));

        pw.println(getArea(firstRect) + getArea(secondRect) 
                - firstIntersect - secondIntersect);
        pw.close();
    }
    public static long getArea(Rectangle r){
	if(r.getWidth() <= 0 || r.getHeight() <= 0){
            return 0;
        }
        return (long)r.getHeight() * (long)r.getWidth();
    }
}

Rectangle Class (C++)

Unfortunately, C++ doesn't have a built in rectangle class, so you need to write the functions yourself. Here is the solution to Blocked Billboard written in C++ (thanks, Brian Dean!).

#include <iostream>
#include <fstream>
using namespace std;

struct Rect{
    int x1, y1, x2, y2;
};

int area(Rect r){
  return (r.y2 - r.y1) * (r.x2 - r.x1);
}

int intersect(Rect p, Rect q){
  int xOverlap = max(0, min(p.x2, q.x2) - max(p.x1, q.x1));
  int yOverlap = max(0, min(p.y2, q.y2) - max(p.y1, q.y1));
  return xOverlap * yOverlap;
}

int main(){
  ifstream cin ("billboard.in");
  ofstream cout ("billboard.out");

  Rect a, b, t;  // billboards a, b, and the truck
 
  cin >> a.x1 >> a.y1 >> a.x2 >> a.y2;
  cin >> b.x1 >> b.y1 >> b.x2 >> b.y2;
  cin >> t.x1 >> t.y1 >> t.x2 >> t.y2;

  cout << area(a) + area(b) - intersect(a, t) - intersect(b, t);
}

Problems