[프로그래머스] 교점에 별 만들기

치즈오믈렛·2023년 2월 7일
0

코딩테스트 연습

목록 보기
2/7

1. 첫 번째 접근

  1. n개 직선 배열에서 2개 조합
  2. 평행한지 확인 후 계속
  3. 정수인지 체크하기
  4. 직선의 교점 구하기
  5. 교점의 최대 x, y 최소 x, y 구하기
  6. 최대 최소를 바탕으로 배열 생성
  7. 교점이 있으면 * 없으면 .
struct Cordinate
{
	public int x;
	public int y;

	public Cordinate(int x, int y)
	{
		this.x = x;
		this.y = y;
	}
}

public string[] solution(int[,] line)
{
	string[] answer = new string[] { };
	List<Cordinate> crossNode = new List<Cordinate>();
	int minX = int.MaxValue;
	int minY = int.MaxValue;
	int maxX = int.MinValue;
	int maxY = int.MinValue;

	// 1. n개 직선 배열에서 2개 조합
	for (int i = 0; i < line.GetLength(0) - 1; i++)
	{
		for (int j = i + 1; j < line.GetLength(0); j++)
		{
			// 2. 평행한지 확인 후 계속
			int denominator = line[i, 0] * line[j, 1] - line[i, 1] * line[j, 0];
			if (denominator == 0)
				continue;
			int numeratorA = line[i, 1] * line[j, 2] - line[i, 2] * line[j, 1];
			int numeratorB = line[i, 2] * line[j, 0] - line[i, 0] * line[j, 2];

			// 3. 정수인지 체크하기
			if (numeratorA % denominator != 0 || numeratorB % denominator != 0)
				continue;

			// 4.직선의 교점 구하기
			int x = numeratorA / denominator;
			int y = numeratorB / denominator;
			crossNode.Add(new Cordinate(x, y));

			// 5. 교점의 최대 x, y 최소 x, y 구하기
			minX = Math.Min(x, minX);
			minY = Math.Min(y, minY);
			maxX = Math.Max(x, maxX);
			maxY = Math.Max(y, maxY);
		}
	}

	// 6. 최대 최소를 바탕으로 배열 생성
	List<string> plotList = new();
	StringBuilder builder = new StringBuilder();
	for (int y = maxY; y > minY - 1; y--)
	{
		for(int x = minX; x < maxX + 1; x++)
		{
			// 7. 교점이 있으면 * 없으면 .
			char point = crossNode.Contains(new(x, y)) ? '*' : '.' ;
			builder.Append(point);
		}
		plotList.Add(builder.ToString());
		builder.Clear();
	}

	answer = plotList.ToArray();
	return answer;
}

결과 : 마지막 테스트 케이스에서 실패

2. 두 번째 접근

  1. 테스트 케이스 하나만 실패한 것으로 봐서 수식과 접근법은 맞은 것 같다.
  2. 제한사항에서 A B C가 최대 100,000인 것을 보아 자료형 문제인 것 같다.
struct Cordinate
{
	public int x;
	public int y;

	public Cordinate(int x, int y)
	{
		this.x = x;
		this.y = y;
	}
}

public string[] solution(int[,] line)
{
	string[] answer = new string[] { };
	List<Cordinate> crossNode = new List<Cordinate>();
	int minX = int.MaxValue;
	int minY = int.MaxValue;
	int maxX = int.MinValue;
	int maxY = int.MinValue;

	// 1. n개 직선 배열에서 2개 조합
	for (int i = 0; i < line.GetLength(0) - 1; i++)
	{
		for (int j = i + 1; j < line.GetLength(0); j++)
		{
			long a = line[i, 0];
			long b = line[i, 1];
			long e = line[i, 2];
			long c = line[j, 0];
			long d = line[j, 1];
			long f = line[j, 2];

			// 2. 평행한지 확인 후 계속
			long denominator = a * d - b * c;
			if (denominator == 0)
				continue;

			long numeratorA = b * f - e * d;
			long numeratorB = e * c - a * f;

			// 3. 정수인지 체크하기
			if (numeratorA % denominator != 0 || numeratorB % denominator != 0)
				continue;

			// 4.직선의 교점 구하기
			int x = (int)(numeratorA / denominator);
			int y = (int)(numeratorB / denominator);
			crossNode.Add(new Cordinate(x, y));

			// 5. 교점의 최대 x, y 최소 x, y 구하기
			minX = Math.Min(x, minX);
			minY = Math.Min(y, minY);
			maxX = Math.Max(x, maxX);
			maxY = Math.Max(y, maxY);
		}
	}

	// 6. 최대 최소를 바탕으로 배열 생성
	List<string> plotList = new List<string>();
	StringBuilder builder = new StringBuilder();
	for (int y = maxY; y > minY - 1; y--)
	{
		for (int x = minX; x < maxX + 1; x++)
		{
			// 7. 교점이 있으면 * 없으면 .
			char point = crossNode.Contains(new Cordinate(x, y)) ? '*' : '.';
			builder.Append(point);
		}
		plotList.Add(builder.ToString());
		builder.Clear();
	}

	answer = plotList.ToArray();
	return answer;
}

결과 : 성공

어려웠던 부분

  1. int * int를 할 때 항상 최대값, 최소값을 신경써야 한다.
  2. 프로그래머스와 visual studio의 작업환경이 다르기 때문에 새로운 기능을 사용할 때 주의해야 한다.
profile
정리노트

0개의 댓글