천천히 빛나는

백준 단계 10 : 기하, 직사각형과 삼각형 (C++) 본문

C++/BAEKJOON (C++)

백준 단계 10 : 기하, 직사각형과 삼각형 (C++)

까만콩 •ᴥ• 2023. 9. 7. 20:34

27323. 정수 A, B 가 주어진다. 세로 길이가 A cm, 가로 길이가 B cm 인 아래와 같은 직사각형의 넓이를 cm2 단위로 구하시오.

#include<iostream>
using namespace std;
int main(){
    int a, b;
    cin >> a >> b;
    cout << a * b;
    return 0;
}

단순한 수학 문제이다.

 

 

 

1085. 한수는 지금 (x, y)에 있다. 직사각형은 각 변이 좌표축에 평행하고, 왼쪽 아래 꼭짓점은 (0, 0), 오른쪽 위 꼭짓점은 (w, h)에 있다. 직사각형의 경계선까지 가는 거리의 최솟값을 구하는 프로그램을 작성하시오.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
    int x, y, w, h;
    cin >> x >> y >> w >> h;
    cout << min({ x, y, h - y, w - x });
    return 0;
}

최소값을 구하기 위해 나는 algorithm의 min 함수를 사용하였다.

 

int a[10] = { 9,3,5,4,1,10,8,6,7,2 };
cout << *max_element(a, a + 10) << endl;

그 외에도 max_element 또는 min_element도 있다.

 

 

 

3009. 세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
	int x[3], y[3];
	for (int i = 0; i < 3; i++)
	{
		cin >> x[i] >> y[i];
	}
	if (x[0] == x[1]) {
		if (y[0] == y[2]) {
			// 0 가운데 낀거
			cout << x[1] + x[2] - x[0] << " " << y[1] + y[2] - y[0];
		}
		else {
			// 1
			cout << x[0] + x[2] - x[1] << " " << y[0] + y[2] - y[1];
		}
	}
	else if (x[0] == x[2]) {
		if (y[0] == y[1]) {
			// 0 가운데 낀거
			cout << x[1] + x[2] - x[0] << " " << y[1] + y[2] - y[0];
		}
		else {
			// 2
			cout << x[0] + x[1] - x[2] << " " << y[0] + y[1] - y[2];
		}
	}
	else {
		if (y[1] == y[0]) {
			// 1
			cout << x[0] + x[2] - x[1] << " " << y[0] + y[2] - y[1];
		}
		else {
			// 2
			cout << x[0] + x[1] - x[2] << " " << y[0] + y[1] - y[2];
		}
	}
    return 0;
}

나는 굳이 중점을 찾는 방식으로 했는데 이것보다 훨씬 쉬운 방법이 있었다.

(10, 10) (10, 20) (30, 20)이 있다면, 쌍이 없는 (30, 10)이 나머지 숫자가 되는 것이다.

 

int main()
{
    int x[3];
    int y[3];
    for(int i = 0; i < 3; i++)
        cin >> x[i] >> y[i];
    if(x[0] == x[1])
        cout << x[2] << " ";
    else if(x[0] == x[2])
        cout << x[1] << " ";
    else
        cout << x[0] << " ";

    if(y[0] == y[1])
        cout << y[2];
    else if(y[0] == y[2])
        cout << y[1];
    else
        cout << y[0];
}

다시 작성한 코드이다.

 

 

 

15894. 성원이는 수학을 정말 못 하는 고등학생이다. 수학을 못하는 대신 근성과 팔 힘이 뛰어난 성원이는 수학 시험에서 수학 지식을 사용하지 않고 근성과 체력을 사용해 문제를 푼다. 지난 시험에서는 아래 사진에 나와있는 문제를 근성과 체력을 사용해 열심히 풀었지만 사진에서 볼 수 있듯이 틀려버리고 말았다!

#include<iostream>
using namespace std;
int main() {
	int n;
	// 4, 8, 12
	cin >> n;
	cout << 4 * n;
    return 0;
}

오류가 발생해서 입력 조건을 다시 확인했다. n은 (1 ≤ n ≤ 10^9)가 된다. int는 약 21억으로 2,100,000,000라고 생각했을 때 약 10^9보다 2배정도 더 크다. 근데 여기서 4배를 해야하니까 int보다 큰 변수타입을 설정해야 하는 것이었다.

int -21억 ~ 21억 (10^9의 2배)
unsigned int 0 ~ 42억
char -128 ~ 127
long long -920경 ~ 920경 (10^18의 9배)
#include<iostream>
using namespace std;
int main() {
	unsigned int n;
	// 4, 8, 12
	cin >> n;
	cout << 4 * n;
    return 0;
}

나는 unsigned int로 바꾸어 주었다.

 

 

 

9063. 임씨의 이름이 새겨진 옥구슬의 위치 N 개가 주어질 때에, 임씨에게 돌아갈 대지의 넓이를 계산하는 프로그램을 작성하시오. 단, 옥구슬의 위치는 2 차원 정수 좌표로 주어지고 옥구슬은 같은 위치에 여러 개가 발견될 수도 있으며, x 축의 양의방향을 동쪽, y 축의 양의방향을 북쪽이라고 가정한다. 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int n;
	cin >> n;
	vector<int>x(n);
	vector<int>y(n);
	for (int i = 0; i < n; i++)
	{
		cin >> x[i] >> y[i];
	}
	int min_x = *min_element(x.begin(), x.end());
	int max_x = *max_element(x.begin(), x.end());
	int min_y = *min_element(y.begin(), y.end());
	int max_y = *max_element(y.begin(), y.end());
	cout << (max_x - min_x) * (max_y - min_y);
    return 0;
}

최소, 최대값을 구해주면 되는 간단한 문제이다.

 

 

 

10101. 창영이는 삼각형의 종류를 잘 구분하지 못한다. 따라서 프로그램을 이용해 이를 외우려고 한다.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int x, y, z;
	cin >> x >> y >> z;
	if (x + y + z != 180) {
		cout << "Error";
	}
	else if ((x == 60) && (y == 60)) {
		cout << "Equilateral";
	}
	else if (x == y || x == z || y == z) {
		cout << "Isosceles";
	}
	else {
		cout << "Scalene";
	}
    return 0;
}

세각의 합이 180이 아닌 경우부터 해주면 if 작성이 비교적 간단해진다.

 

 

 

5073. 삼각형의 세 변의 길이가 주어질 때 변의 길이에 따라 다음과 같이 정의한다.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int x, y, z;
	while (1) {
		cin >> x >> y >> z;
		if (x == 0 && y == 0 && z == 0)
			break;

		if (x == y && x == z && y == z) {
			cout << "Equilateral\n";
			continue;
		}
		if (max({ x, y, z }) == x) {
			if (x >= y + z) {
				cout << "Invalid\n";
				continue;
			}
		}
		else if (max({ x, y, z }) == y) {
			if (y >= x + z) {
				cout << "Invalid\n";
				continue;
			}
		}
		else {
			if (z >= x + y) {
				cout << "Invalid\n";
				continue;
			}
		}
		if (x == y || y == z || x == z)
			cout << "Isosceles\n";
		else
			cout << "Scalene\n";
	}
    return 0;
}

나는 sort 기능을 까먹어서 이렇게 했는데 다른 코드를 보니까 오름차순 정리를 하시는걸 보고 급히 수정했다...

 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int triangle[3];
	while (1) {
		for (int i = 0; i < 3; i++)
		{
			cin >> triangle[i];
		}
		if (triangle[0] == 0 && triangle[0] == triangle[1] && triangle[0] == triangle[2])
		{
			break;
		}
		if (triangle[0] == triangle[1] && triangle[1] == triangle[2])
		{
			cout << "Equilateral\n";
			continue;
		}
		sort(begin(triangle), end(triangle));
		if (triangle[0] + triangle[1] <= triangle[2])
		{
			cout << "Invalid\n";
			continue;
		}

		if (triangle[0] == triangle[1] || triangle[1] == triangle[2] || triangle[0] == triangle[2])
			cout << "Isosceles\n";
		else
			cout << "Scalene\n";
	}
    return 0;
}

sort를 이용하면 이와같이 된다.

 

 

 

14215. 영선이는 길이가 a, b, c인 세 막대를 가지고 있고, 각 막대의 길이를 마음대로 줄일 수 있다.

#include<iostream>
#include<algorithm>
#include <numeric>
using namespace std;
int main() {
	int tri[3];
	for (int i = 0; i < 3; i++)
	{
		cin >> tri[i];
	}
	sort(begin(tri), end(tri));
	while (tri[0] + tri[1] <= tri[2]) {
		tri[2]--;
	}
	cout << accumulate(begin(tri), end(tri), 0);
    return 0;
}

이번 문제에서는 accumulate에 대해 설명하도록 하겠다.

 

#include <numeric>
vector<int> v = { 1, 2, 3, 4, 5 };
cout << accumulate(v.begin(), v.end(), 0) << '\n';

벡터 또는 배열에서 쓸 수 있는 함수로 벡터 또는 배열의 합을 계산해준다. numeric 헤더에 포함되어 있다.

첫번째는 begin, 두번째는 end, 세번째는 초기값이다. 세번째 초기값에 따라 accumulate의 반환 타입이 정해지므로, long long int 타입을 반환받고 싶으면 0LL과 같이 적어주어야 한다.