나는 컴공이다/대회 후기

2021 신촌지역 대학생 프로그램이 대회 동아리 연합 겨울 대회(SUAPC 2021 Winter) 참가 후기

김짱짱 2021. 3. 4. 21:45

www.acmicpc.net/contest/view/586

 

2021 신촌지역 대학생 프로그래밍 대회 동아리 연합 겨울 대회 (SUAPC 2021 Winter)

사용 가능한 언어 C++17 Python 3 C11 PyPy3 C++11 C++14 Java 8 (OpenJDK) C++20 Kotlin (JVM)

www.acmicpc.net

대회는 2021년 2월 28일 일요일 오후 12시부터 5시까지 총 다섯 시간동안 진행되었다.

(원래 평소에 2시쯤에 일어나는데 시간 맞춰 일어나느라 쪼끔 힘들었다ㅎㅎ)

 

15등으로 마무리~

우리 팀은 총 다섯 문제를 풀어서 15등으로 마무리했다.

많이 푼 건 아니지만 지난 대회 때 두 문제 풀었던 거 생각하면 꽤나 발전한 거라고 생각한다....ㅎㅎ

 

그 중에서 내가 푼 문제는 두 문제!

B번 떡국 문제와 K번 합성인수분해 문제였다. (둘 다 한 번씩 틀렸다.ㅎㅎㅎ)

 

B. 떡국

www.acmicpc.net/problem/20937

 

20937번: 떡국

Naver D2를 아시나요? D2는 For Developers, By Developers의 약자로, 개발자들을 위해 개발자들이 직접 만들어 가고 있는 네이버 개발자 지원 프로그램입니다. 네이버가 축적한 기술과 지식을 공유하고, 외

www.acmicpc.net

※ 풀이 방법

이 문제에서 떡국 그릇 크기의 입력 순서는 답과 상관이 없다. 떡국 그릇탑의 개수를 최소화하기 위해서는 하나의 탑에 최대한 많은 수의 그릇을 쌓으면 된다. 여기서 그릇의 크기가 다르면 어떻게든 같은 탑 안에 쌓을 수 있지만 크기가 같을 경우 같은 탑 안에 쌓을 수 없다는 것이 중요한 포인트이다. 

 

따라서 

떡국 그릇탑의 최소 개수 = max(Xi) (Xi=크기가 i인 그릇의 개수)

라고 볼 수 있다.

 

그릇의 크기를 입력받을 때마다 크기에 맞는 Xi값을 증가시키고 입력을 다 받은 뒤 최댓값을 구해주면 답을 구할 수 있다.

 

※ 코드

import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st;
		
		String s=br.readLine();
		int N=Integer.parseInt(s);
		
		s=br.readLine();
		int [] a=new int[50001];
		st=new StringTokenizer(s);
		
		int count=0;
		boolean ck=false;
		
		int temp;
		
		for(int i=0;i<N;i++) {
			temp=Integer.parseInt(st.nextToken());//그릇의 크기 입력받기
			a[temp]++;//temp 크기의 그릇의 개수 업데이트
		}
		
        //최댓값 구하기
		for(int i=1;i<=50000;i++) {
			if(a[i]>count) count=a[i];
		}
		
		bw.write(count+"\n");
		bw.flush();
		bw.close();
	}

}

 

K. 합성인수분해

www.acmicpc.net/problem/20946

 

20946번: 합성인수분해

수열 $A = a_1, a_2, \dots, a_n$가 수열 $B = b_1, b_2, \dots, b_m$보다 사전 순으로 앞선다는 것의 엄밀한 정의는, 다음 중 하나를 만족한다는 것이다. $a_1=b_1,\ a_2=b_2,\ \dots,\ a_{i-1}=b_{i-1}$이고 $a_i < b_i$인 $i$가

www.acmicpc.net

※ 풀이 방법

문제 이름은 합성인수분해이지만 사실상 소인수분해를 하는 문제이다.

주어진 N의 소인수 분해를 해주고 작은 수부터 두 숫자씩 곱해서 출력하면 사전순으로 가장 앞서는 합성인수분해가 된다. 

합성인수분해가 불가능한 경우는 주어진 N이 소수인 경우밖에 없다. 소인수분해 결과 소인수가 하나도 없을 경우 -1을, 아닐 경우 앞에서 설명한 것과 같이 구한 소인수를 두 개씩 묶어서 출력하면 된다.

여기서 소인수의 개수가 홀수인 경우에는 마지막에 소인수 두 개가 아닌 세 개를 묶어서 출력해야한다. (처음에 이걸 생각 안 해서 틀렸다....ㅎㅎ)

 

※ 코드

import java.util.*;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input=new Scanner(System.in);
		
		long N=input.nextLong();
		
		ArrayList<Long> num=new ArrayList<Long>();///소인수 저장할 ArrayList
		
		long n=N;
		
		for(long i=2;i*i<=N;i++) {//소인수분해
			if(n%i!=0) continue;
			while(n%i==0) {
				num.add(i);
				n/=i;
			}
		}
		
		if(n!=1) num.add(n);
		
		long temp;
		
		if(num.size()>1) {//num이 소수가 아니라면
			if(num.size()%2==0) {//인수의 개수가 짝수일 경우
				for(int i=0;i<num.size();i+=2) {//두 개씩 묶어서 출력
					temp=num.get(i)*num.get(i+1);
					System.out.print(temp+" ");
				}
			}
			else {//소인수의 개수가 홀수일 경우
				for(int i=0;i<num.size()-3;i+=2) {//두 개씩 묶어서 출력
					temp=num.get(i)*num.get(i+1);
					System.out.print(temp+" ");
				}
				temp=1;
				for(int i=num.size()-3;i<num.size();i++)//마지막에는 세 개 묶어서 출력
					temp*=num.get(i);
				System.out.println(temp);
			}
		}
		else System.out.println(-1);//num이 소수일 경우 -1 출력
	}

}

 

 ※ (진짜) 참가 후기

문제를 많이 풀지는 못 했지만 어느 정도 풀었다는 거에서 만족한다. 다음 대회에서는 반 이상 풀 수 있었으면 좋겠다....!

F번 성싶당 문제도 그레이 코드를 사용해야한다는 것까지는 알아냈는데 시간 내에 구현을 못해서 아쉬웠다. 

대회 끝나고 스트리밍도 봤는데 손도 못 댄 문제는 풀이를 들어도 모르겠더라...😏😏

운영진분들이 특별상도 많이 준비하셨는데 우리 팀은 하나도 못 받아서 아쉽다....😂😂

그래도 방학동안 공부한 것을 점검하고 방학을 마무리했다는 것에 큰 의미를 두고 있다.

다음 대회에서는 입상 노려보자....! (예은이) 화이팅....!