IT 프로그래밍/객체지향프로그래밍

객체지향프로그래밍 4 과제

기술1 2024. 6. 21. 14:27
반응형

1번

문제 설명

1. 파일 input1.txt 에서 도형의 정보가 주어집니다. 도형은 사각형과 원으로 구성됩니다.

2. 도형의 정보는 각 도형의 종류 (R 또는 C)와 좌표 및 크기로 표현됩니다.

3. 파일의 마지막 줄에는 원의 중심 좌표와 반지름이 주어집니다. 이 원과 교차하는 도형들을 면적순으로 정렬하여 출력해야 합니다. 

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

class Point {
private:
    double x, y;

public:
    Point(double a = 0, double b = 0) : x(a), y(b) {}

    double getX() const { return x; }
    double getY() const { return y; }

    double distSq(const Point& p) const {
        return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
    }
};

class Shape {
public:
    virtual double area() const = 0;
    virtual bool intersects(const Point& center, double radius) const = 0;
    virtual void print() const = 0;
    virtual ~Shape() {}
};

class Circle : public Shape {
private:
    Point center;
    double radius;

public:
    Circle(Point c, double r) : center(c), radius(r) {}

    double area() const override {
        return 3.141592 * radius * radius;
    }

    bool intersects(const Point& c, double r) const override {
        double dist = sqrt(center.distSq(c));
        return dist <= (radius + r);
    }

    void print() const override {
        cout << "C " << center.getX() << " " << center.getY() << " " << radius << endl;
    }
};

class Rect : public Shape {
private:
    Point lu, rl; 

public:
    Rect(Point a, Point b) : lu(a), rl(b) {}

    double area() const override {
        return abs(rl.getX() - lu.getX()) * abs(rl.getY() - lu.getY());
    }

    bool intersects(const Point& center, double radius) const override {

        if (center.getX() >= lu.getX() && center.getX() <= rl.getX() &&
            center.getY() >= lu.getY() && center.getY() <= rl.getY()) {
            return true;
        }

        double nearestX = max(lu.getX(), min(center.getX(), rl.getX()));
        double nearestY = max(lu.getY(), min(center.getY(), rl.getY()));
        double deltaX = center.getX() - nearestX;
        double deltaY = center.getY() - nearestY;
        return (deltaX * deltaX + deltaY * deltaY) <= (radius * radius);
    }

    void print() const override {
        cout << "R " << lu.getX() << " " << rl.getX() << " " << lu.getY() << " " << rl.getY() << endl;
    }
};

int main() {
    ifstream fin("input1.txt");
    if (!fin) {
        cerr << "Not open file" << endl;
        return 1;
    }

    int n;
    fin >> n;
    vector<Shape*> shapes;

    for (int i = 0; i < n; ++i) {
        char type;
        double x1, x2, y1, y2;
        fin >> type;
        if (type == 'R') {
            fin >> x1 >> x2 >> y1 >> y2;
            shapes.push_back(new Rect(Point(min(x1, x2), min(y1, y2)), Point(max(x1, x2), max(y1, y2))));
        }
        else if (type == 'C') {
            double r;
            fin >> x1 >> y1 >> r;
            shapes.push_back(new Circle(Point(x1, y1), r));
        }
    }

    double x, y, r;
    fin >> x >> y >> r;
    Point center(x, y);
    Circle query(center, r);

    vector<Shape*> intersectingShapes;

    for (auto* shape : shapes) {
        if (shape->intersects(center, r)) {
            intersectingShapes.push_back(shape);
        }
    }

    sort(intersectingShapes.begin(), intersectingShapes.end(), [](Shape* a, Shape* b) {
        return a->area() < b->area();
        });

    for (auto* shape : intersectingShapes) {
        shape->print();
    }

    for (auto* shape : shapes) {
        delete shape;
    }

    return 0;
}

 

포인트 클래스

class Point {
private:
    double x, y;

public:
    Point(double a = 0, double b = 0) : x(a), y(b) {}

    double getX() const { return x; }
    double getY() const { return y; }

    double distSq(const Point& p) const {
        return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
    }
};

좌표를 나타내는 포인트 클래스입니다. distSq 메서드는 두 점 사이 거리 제곱을 계산합니다. 

 

Shape 추상 클래스

class Shape {
public:
    virtual double area() const = 0;
    virtual bool intersects(const Point& center, double radius) const = 0;
    virtual void print() const = 0;
    virtual ~Shape() {}
};

 

Circle 클래스

class Circle : public Shape {
private:
    Point center;
    double radius;

public:
    Circle(Point c, double r) : center(c), radius(r) {}

    double area() const override {
        return 3.141592 * radius * radius;
    }

    bool intersects(const Point& c, double r) const override {
        double dist = sqrt(center.distSq(c));
        return dist <= (radius + r);
    }

    void print() const override {
        cout << "C " << center.getX() << " " << center.getY() << " " << radius << endl;
    }
};

 

Rect 클래스에서는 interestcs 메서드는 사각형과 원의 교차 여부를 판단합니다. 

 

2번문제

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

class Point {
public:
    double x, y;
};

double distance(const Point& a, const Point& b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

Point findCircleCenter(const vector<Point>& points) {
    Point center;
    center.x = 0;
    center.y = 0;
    int n = points.size();
    for (const auto& p : points) {
        center.x += p.x;
        center.y += p.y;
    }
    center.x /= n;
    center.y /= n;
    return center;
}

int main() {
    ifstream inFile("input2.txt");
    int N;
    inFile >> N;
    vector<Point> rectCenters(N);
    vector<vector<Point>> rectangles(N);  // 각 사각형의 꼭짓점 저장

    double xMin, xMax, yMin, yMax;

    for (int i = 0; i < N; i++) {
        inFile >> xMin >> xMax >> yMin >> yMax;
        rectCenters[i].x = (xMin + xMax) / 2.0;
        rectCenters[i].y = (yMin + yMax) / 2.0;
        rectangles[i] = { {xMin, yMin}, {xMin, yMax}, {xMax, yMin}, {xMax, yMax} };
    }

    Point center = findCircleCenter(rectCenters);
    double maxRadius = 0;

    for (int i = 0; i < N; i++) {
        for (const auto& vertex : rectangles[i]) {
            double radius = distance(center, vertex);
            maxRadius = max(maxRadius, radius);
        }
    }

    cout << "Center: (" << center.x << ", " << center.y << ")\n";
    cout << "Radius: " << maxRadius << endl;

    inFile.close();
    return 0;
}

이 프로그램은 입력된 여러 사각형을 포함하는 가장 작은 원의 중심과 반지름을 계산하는 프로그램입니다. 각 사각형은 사각형의 좌표를 나타내는 네 개의 값으로 주어집니다. 

 

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

표준 임출력 라이브러리 iostream, fstream은 파일 입출력, cmate는 수학함수를 사용하기 위한 것이며 vector는 벡터 자료구조를 사용하기 위한 것입니다. algorithm은 알고리즘 함수를 사용

 

 

포인트 클래스 정의

class Point {
public:
    double x, y;
};

point 클래스는 2차원 좌표계를 나타냅니다. x와 y 좌표를 멤버 변수로 두고 있습니다.

 

두 점 사이의 거리 계산 함수

double distance(const Point& a, const Point& b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

distance 함수는 두 점 a와 b 사이의 유클리드 거리를 계산합니다. sqrt는 제곱근을 계산합니다.

 

 

중심 찾기 함수

Point findCircleCenter(const vector<Point>& points) {
    Point center;
    center.x = 0;
    center.y = 0;
    int n = points.size();
    for (const auto& p : points) {
        center.x += p.x;
        center.y += p.y;
    }
    center.x /= n;
    center.y /= n;
    return center;
}

findCircleCenter 함수는 주어진 포인트들의 평균을 계산하여 중심점을 찾습니다. 각 포인트의 x와 y값을 더한 후 포인트의 개수로 나누어 중심 좌표를 계산합니다. 

 

메인 함수

int main() {
    ifstream inFile("input2.txt");
    int N;
    inFile >> N;
    vector<Point> rectCenters(N);
    vector<vector<Point>> rectangles(N);  // 각 사각형의 꼭짓점 저장

    double xMin, xMax, yMin, yMax;

    for (int i = 0; i < N; i++) {
        inFile >> xMin >> xMax >> yMin >> yMax;
        rectCenters[i].x = (xMin + xMax) / 2.0;
        rectCenters[i].y = (yMin + yMax) / 2.0;
        rectangles[i] = { {xMin, yMin}, {xMin, yMax}, {xMax, yMin}, {xMax, yMax} };
    }

    Point center = findCircleCenter(rectCenters);
    double maxRadius = 0;

    for (int i = 0; i < N; i++) {
        for (const auto& vertex : rectangles[i]) {
            double radius = distance(center, vertex);
            maxRadius = max(maxRadius, radius);
        }
    }

    cout << "Center: (" << center.x << ", " << center.y << ")\n";
    cout << "Radius: " << maxRadius << endl;

    inFile.close();
    return 0;
}

ifstream을 통해 input2.txt 파일을 엽니다. 파일에서 사각형의 개수 N을 읽어옵니다. 

 

벡터 초기화

vector<Point> rectCenters(N);
vector<vector<Point>> rectangles(N);  // 각 사각형의 꼭짓점 저장

사각형 중심점을 저장할 rectCenters 벡터와 사각형 꼭짓점을 저장할 rectangles 벡터를 초기화합니다. 

 

사각형 좌표 읽기 및 저장

double xMin, xMax, yMin, yMax;

for (int i = 0; i < N; i++) {
    inFile >> xMin >> xMax >> yMin >> yMax;
    rectCenters[i].x = (xMin + xMax) / 2.0;
    rectCenters[i].y = (yMin + yMax) / 2.0;
    rectangles[i] = { {xMin, yMin}, {xMin, yMax}, {xMax, yMin}, {xMax, yMax} };
}

각 사각형의 좌표를 파일에서 읽어와 저장합니다. 사각형의 중심점을 계산하여 rectCenters 벡터에 저장합니다. 사각형의 네 꼭짓점을 rectangles 벡터에 저장합니다. 

 

중심점 계산

Point center = findCircleCenter(rectCenters);

모든 사각형의 중심점으로부터 원의 중심점을 계산합니다. 

 

최대 반지름 계산

double maxRadius = 0;

for (int i = 0; i < N; i++) {
    for (const auto& vertex : rectangles[i]) {
        double radius = distance(center, vertex);
        maxRadius = max(maxRadius, radius);
    }
}

각 사각형의 꼭짓점과 계산된 중심점 사이의 거리를 계산합니다. 그 중 가장 큰 거리를 maxRadius로 설정합니다. 

 

cout << "Center: (" << center.x << ", " << center.y << ")\n";
cout << "Radius: " << maxRadius << endl;

계산된 중심점과 반지름을 출력합니다.

 

이 프로그램은 주어진 입력 파일을 읽어 각 사각형의 중심을 계산하고,그 중심점으로부터 가장 작은 원의 중심과 반지름을 계산하여 출력합니다. 이를 통해 모든 사각형을 포함하는 원을 구할 수 있습니다. 

 

2번 응용 문제 

주어진 다각형들을 포함하는 가장 작은 원의 중심과 반지름을 구하는 프로그램을 작성하세요. 입력은 input3.txt 파일로 주어지며, 파일의 첫 줄에는 다각형의 개수 N이 주어집니다. 다음 N줄에는 각 다각형의 꼭짓점 좌표가 주어지며, 각 줄은 
M개의 좌표로 구성되어 있습니다. (예: 다각형의 꼭짓점의 개수와 각 좌표는 공백으로 구분됩니다.)

 

3
4 1 1 1 3 3 3 3 1
5 2 2 2 5 5 5 5 2 3 3
4 0 0 0 4 4 4 4 0
Center: (2.5, 2.5)
Radius: 3.53553
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

class Point {
public:
    double x, y;
};

double distance(const Point& a, const Point& b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

Point findCircleCenter(const vector<Point>& points) {
    Point center;
    center.x = 0;
    center.y = 0;
    int n = points.size();
    for (const auto& p : points) {
        center.x += p.x;
        center.y += p.y;
    }
    center.x /= n;
    center.y /= n;
    return center;
}

int main() {
    ifstream inFile("input3.txt");
    int N;
    inFile >> N;
    vector<Point> allVertices;

    for (int i = 0; i < N; i++) {
        int M;
        inFile >> M;
        vector<Point> polygon(M);
        for (int j = 0; j < M; j++) {
            inFile >> polygon[j].x >> polygon[j].y;
            allVertices.push_back(polygon[j]);
        }
    }

    Point center = findCircleCenter(allVertices);
    double maxRadius = 0;

    for (const auto& vertex : allVertices) {
        double radius = distance(center, vertex);
        maxRadius = max(maxRadius, radius);
    }

    cout << "Center: (" << center.x << ", " << center.y << ")\n";
    cout << "Radius: " << maxRadius << endl;

    inFile.close();
    return 0;
}

 

 

2번 응용 문제 2 

주어진 여러 개의 원을 포함하는 가장 작은 원의 중심과 반지름을 구하는 프로그램을 작성하세요. 입력은 input4.txt 파일로 주어지며, 파일의 첫 줄에는 원의 개수  N이 주어집니다. 각 원은 중심 좌표와 반지름으로 표현됩니다.

 

문제 해설:

- 파일의 첫 줄에는 원의 개수 N이 주어집니다.
- 각 원의 중심 좌표 (x, y)와 반지름 r이 주어집니다.
- 모든 원을 포함하는 가장 작은 원의 중심과 반지름을 구합니다.

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

class Circle {
public:
    double x, y, r;
};

class Point {
public:
    double x, y;
};

double distance(const Point& a, const Point& b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

Point findCircleCenter(const vector<Circle>& circles) {
    Point center;
    center.x = 0;
    center.y = 0;
    int n = circles.size();
    for (const auto& c : circles) {
        center.x += c.x;
        center.y += c.y;
    }
    center.x /= n;
    center.y /= n;
    return center;
}

int main() {
    ifstream inFile("input4.txt");
    int N;
    inFile >> N;
    vector<Circle> circles(N);

    for (int i = 0; i < N; i++) {
        inFile >> circles[i].x >> circles[i].y >> circles[i].r;
    }

    Point center = findCircleCenter(circles);
    double maxRadius = 0;

    for (const auto& c : circles) {
        Point circleCenter = {c.x, c.y};
        double radiusToEdge = distance(center, circleCenter) + c.r;
        maxRadius = max(maxRadius, radiusToEdge);
    }

    cout << "Center: (" << center.x << ", " << center.y << ")\n";
    cout << "Radius: " << maxRadius << endl;

    inFile.close();
    return 0;
}

 

 

원을 포함하는 가장 작은 사각형의 중심과 변의 길이를 구하는 프로그

3
2.0 2.0 1.0
4.0 4.0 1.5
6.0 6.0 1.0

입력예시

Center: (4.0, 4.0)
Side Length: 8.0

 

 

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

class Circle {
public:
    double x, y, r;
};

int main() {
    ifstream inFile("input4.txt");
    int N;
    inFile >> N;
    vector<Circle> circles(N);

    for (int i = 0; i < N; i++) {
        inFile >> circles[i].x >> circles[i].y >> circles[i].r;
    }

    // 최소와 최대 x, y 값을 초기화합니다.
    double xMin = circles[0].x - circles[0].r;
    double xMax = circles[0].x + circles[0].r;
    double yMin = circles[0].y - circles[0].r;
    double yMax = circles[0].y + circles[0].r;

    // 각 원의 경계 좌표를 통해 전체 최소, 최대 x, y 값을 업데이트합니다.
    for (const auto& c : circles) {
        xMin = min(xMin, c.x - c.r);
        xMax = max(xMax, c.x + c.r);
        yMin = min(yMin, c.y - c.r);
        yMax = max(yMax, c.y + c.r);
    }

    // 사각형의 중심 좌표를 계산합니다.
    double centerX = (xMin + xMax) / 2.0;
    double centerY = (yMin + yMax) / 2.0;

    // 사각형의 변의 길이를 계산합니다.
    double sideLength = max(xMax - xMin, yMax - yMin);

    cout << "Center: (" << centerX << ", " << centerY << ")\n";
    cout << "Side Length: " << sideLength << endl;

    inFile.close();
    return 0;
}
반응형