알고리즘/Samsung codeground

11/18 다트 게임

삼성 코드그라운드에서 제공하는 알고리즘에 관한 개인적인 풀이를 정리했습니다.

아래 사이트에서 직접 풀어보실 수 있습니다.

 

https://www.codeground.org/practice

불러오는 중입니다...

 

모든 알고리즘 문제는 C++로 구현되어 있습니다.

 

출처 : https://www.codeground.org/practice/practiceProblemViewNew

 

나는 main 메소드 외에 2개의 메소드 getScore(x, y), getSqrt(x, y)를 사용했다. getScore 함수는 다트의 x축을 기준으로 한 각도를 구해서 그 점수를 반환하며, getSqrt(x, y)는 원점에서 (x, y)까지의 거리를 구하여 리턴한다. 각 함수는 다음과 같이 구현되어있다. 각 함수는 다음과 같다.

double getSqrt(int x, int y) {
	return sqrt(x * x + y * y);
}

getSqrt 메소드.

 

 

 

double getScore(int x, int y) {
	double arc = atan2(y, x) * 180 / PI;
	if (arc < 0) arc += 360;
	int i, idx = 0;
	idx = (int)((arc + 9) / 18) % 20;
	return score[idx];
}

getScore 메소드. cmath 라이브러리의 atan2 메소드를 사용한다.

 

 

 

getSqrt 메소드는 원점에서 (x, y) 까지의 거리를 구하는 간단한 코드이므로 설명을 생략하고, getScore 메소드를 살펴보자.

 

 

 

기본적으로 cmath 라이브러리의 atan2(x, y) 메소드를 사용하여 x축과 점 (x, y) 사이의 각도를 구한다. atan2 메소드는 리턴값이 -π ~ π 사이이므로 먼저 180/PI 를 곱하여 -180~180 사이의 값으로 만들어주고, 음수값이 나오면 360을 더하여 값의 범위를 0~360 사이로 만들었다.

 

 

 

다트칸이 20등분 되어있으므로 각 칸은 18도를 차지하며, 첫 칸(점수 6)이 -9~9도를 차지하므로 arc 값에 9를 더하여 이를 20과 나머지 연산 해주면 점수 6에 해당하는 칸부터 시계 반대방향으로 0(점수 6에 해당하는 칸) 부터 19(점수 10에 해당하는 칸)까지의 인덱스를 구할 수 있다. 다트판의 각 점수들을 미리 넣어둔 int형 배열 score에서 인덱스에 해당하는 값을 통해 각 다트가 해당하는 값을 구할 수 있다.

 

 

 

이제 getSqrt에 점 (x, y)를 넣어 거리를 얻고 다음과 같이 다트로 얻을 최종 점수를 구할 수 있다.

                      

distance < (BULL의 반지름) -> 50점

distance < (TRIPLE 시작 구간의 반지름) -> getScore(x, y)

distance < (TRIPLE 종료 구간의 반지름) -> 3 * getScore(x, y)

distance < (DOUBLE 시작 구간의 반지름) -> getScore(x, y)

distance < (DOUBLE 종료 구간의 반지름) -> 2 * getScore(x, y)

이외의 경우에는 0점

 

전체 코드는 다음과 같다.

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

int Answer; //다트 게임
int score[20] = { 6, 13, 4, 18, 1, 20, 5, 12, 9, 14, 11, 8, 16, 7, 19, 3, 17, 2, 15, 10 };
const double PI = 3.1415926535;
double getSqrt(int x, int y) {
	return sqrt(x * x + y * y);
}

double getScore(int x, int y) {
	double arc = atan2(y, x) * 180 / PI;
	if (arc < 0) arc += 360;
	int i, idx = 0;
	idx = (int)((arc + 9) / 18) % 20;
	return score[idx];
}

int main(int argc, char** argv)
{
	int T, test_case;

	// freopen("input.txt", "r", stdin);

	cin >> T;

	for (test_case = 0; test_case < T; test_case++)
	{

		Answer = 0;
		// Print the answer to standard output(screen).

		int i, n, x, y;
		double br, tsr, ter, dsr, der;

		cin >> br >> tsr >> ter >> dsr >> der >> n;
		for (i = 0; i < n; i++) {
			cin >> x >> y;
			double rad = getSqrt(x, y);
			if (rad <= br) Answer += 50;
			else if (rad < tsr) {
				Answer += getScore(x, y);
			}
			else if (rad < ter) {
				Answer += 3 * getScore(x, y);
			}
			else if (rad < dsr) {
				Answer += getScore(x, y);
			}
			else if (rad < der) {
				Answer += 2 * getScore(x, y);
			}
		}


		cout << "Case #" << test_case + 1 << endl;
		cout << Answer << endl;
	}

	return 0;
}

'알고리즘 > Samsung codeground' 카테고리의 다른 글

11/22 블럭 없애기  (0) 2019.11.22
11/19 좋은 수  (0) 2019.11.19
11/19 미궁 속의 방  (0) 2019.11.19
11/18 이항계수의 합  (0) 2019.11.18