코딩테스트/구현(Implementation)

[Java] 백준 2456 : 나는 학급회장이다

sujin7837 2022. 1. 26. 19:51
반응형

문제

N명의 학생들이 모인 초등학교 반에서 학급회장 선거를 하려고 한다. 그 중 3명이 회장후보로 나왔고, 이들에 대한 선호도를 N명의 학생들 각각에게 적어내도록 하였다. 세 명의 후보는 후보 1번, 후보 2번, 후보 3번이라 한다.

모든 학생은 3명의 후보 중에서 가장 선호하는 후보에게는 3점, 두 번째로 선호하는 후보에게는 2점, 가장 선호하지 않는 후보에게는 1점을 주어야 한다. 3명의 후보에 대한 한 학생의 선호 점수는 모두 다르며, 1점, 2점, 3점이 정확히 한 번씩 나타나야 한다. 

후보의 최종 점수는 학생들로부터 받은 자신의 선호도 점수를 모두 더한 값이 된다. 그러면 3명의 후보 중 가장 큰 점수를 받은 후보가 회장으로 결정된다. 단, 점수가 가장 큰 후보가 여러 명인 경우에는 3점을 더 많이 받은 후보를 회장으로 결정하고, 3점을 받은 횟수가 같은 경우에는 2점을 더 많이 받은 후보를 회장으로 결정한다. 그러나 3점과 2점을 받은 횟수가 모두 동일하면, 1점을 받은 횟수도 같을 수밖에 없어 회장을 결정하지 못하게 된다.

여러분은 선호도 투표를 통해 얻은 세 후보의 점수를 계산한 후, 유일하게 회장이 결정되는 경우에는 회장으로 결정된 후보의 번호(1, 2, 3 중 한 번호)와 최고 점수를 출력하고, 회장을 결정하지 못하는 경우에는 번호 0과 최고 점수를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에는 반의 학생들의 수 N (3 ≤ N ≤ 1,000)이 주어진다. 다음 N개의 각 줄에는 각 학생이 제출한 회장후보 3명에 대한 선호 점수가 주어지는 데, 첫 번째 점수는 후보 1번에 대한 점수이고 두 번째 점수는 후보 2번에 대한 점수이고 세 번째 점수는 후보 3번에 대한 점수이다. 이 세 점수는 서로 다르며, 1, 2, 3이 정확히 한 번씩 나타난다. 

출력

학생들의 선호도 투표 결과로부터, 회장이 유일하게 결정되는 경우에는 회장으로 결정된 후보의 번호와 최고 점수를 출력하고, 유일하게 결정할 수 없는 경우에는 0과 최고 점수를 출력한다.

예제 입력 1

6
3 1 2
2 3 1
3 1 2
1 2 3
3 1 2
1 2 3

예제 출력 1

1 13

예제 입력 2

6
1 2 3
3 1 2
2 3 1
1 2 3
3 1 2
2 3 1

예제 출력 2

0 12

 

소스코드

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	private static int N;
	private static int score[][];	// [학생 수][점수]
	private static int scoreCnt[][];	// [후보 번호][점수 개수]
	private static List<Integer> idxOfScore=new ArrayList<Integer>();
	
	public static int isSame(int arr[], int m) {	// 최대 점수(m)를 갖는 후보가 몇 명인지 구하는 메서드
		int cnt=0;
		for(int i=1;i<arr.length;i++) {
			if(arr[i]==m) {
				cnt++;
				idxOfScore.add(i);	// 최대 점수(m)를 갖는 후보의 번호를 idOfScore에 저장
			}
		}
		return cnt;
	}
	
	public static int compTwo(int a, int b) {	// 최대 점수를 갖는 후보가 2명 이상인 경우,
		if(scoreCnt[a][3]!=scoreCnt[b][3]) {	// 3점의 개수를 비교
			return scoreCnt[a][3] > scoreCnt[b][3] ? a : b;
		}
		else if(scoreCnt[a][2]!=scoreCnt[b][2]) {	// 3점의 개수가 같은 경우, 2점의 개수를 비교
			return scoreCnt[a][2] > scoreCnt[b][2] ? a : b;
		} else {	// 3점과 2점의 개수가 같은 경우 0 리턴
			return 0;
		}
			
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int total[]=new int[4];
		
		N=sc.nextInt();
		score=new int[N+1][4];
		scoreCnt=new int[4][4];
		for(int i=1;i<=N;i++) {
			score[i][1]=sc.nextInt();
			scoreCnt[1][score[i][1]]++;
			total[1]+=score[i][1];
			
			score[i][2]=sc.nextInt();
			scoreCnt[2][score[i][2]]++;
			total[2]+=score[i][2];
			
			score[i][3]=sc.nextInt();
			scoreCnt[3][score[i][3]]++;
			total[3]+=score[i][3];
		}

		int maxVal=0;
		int resultNum=-1;
		int resultScore=-1;
		for(int i=1;i<=3;i++) {
			if(total[i]>maxVal) {
				resultNum=i;
				maxVal=total[i];
			}
		}
		if(isSame(total, maxVal)==1) {	// 최대 점수를 갖는 후보가 1명인 경우
			resultScore=maxVal;
		} else if(isSame(total, maxVal)==2) {	// 최대 점수를 갖는 후보가 2명인 경우
			int a=idxOfScore.get(0);
			int b=idxOfScore.get(1);
			resultNum=compTwo(a, b);
			if(resultNum==0) resultScore=maxVal;
			else resultScore=total[resultNum];
		} else if(isSame(total, maxVal)==3) {	// 최대 점수를 갖는 후보가 3명인 경우
			int a=idxOfScore.get(0);
			int b=idxOfScore.get(1);
			int c=idxOfScore.get(2);
			resultNum=compTwo(a,b);
			if(resultNum==0) resultNum=a;
			resultNum=compTwo(resultNum,c);
			if(resultNum==0) resultScore=maxVal;
			else resultScore=total[resultNum];
		}
		System.out.println(resultNum+" "+resultScore);
	}
}
반응형