문제 설명

1. M 개의 원소로 이루어진 집합에서 N 개의 원소로 이루어진 부분집합의 개수를 구하면 되는 문제다.

풀이

1. 조합의 개수는 n!/(k!(n-k)!)이므로 오버플로우를 방지하기 위해 나눗셈과 곱셈을 동시에 처리한다.

코드

import java.util.*;
import java.io.*;
/**
* https://www.acmicpc.net/problem/1010
* BOJ 백준온라인져지 1010 다리 놓기 풀이
*/
public class Main {
private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
for (int z = 0; z < N; z++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int k = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());
int result = 1;
for (int i = 1; i <= k; i++) {
result = result * (n - i + 1) / i;
}
bw.write(result + "\n");
}
bw.flush();
}
}
view raw Main.java hosted with ❤ by GitHub

문제

재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 강이 흐르고 있다. 하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리를 짓기로 결심하였다. 강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다. 재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)

재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.) 재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다. 다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

출력

각 테스트 케이스에 대해 주어진 조건하에 다리를 지을 수 있는 경우의 수를 출력한다.

예제 입력 1 

3
2 2
1 5
13 29

예제 출력 1 

1
5
67863915

출처

  • 문제를 만든 사람: i274


스터디에서 순열과 조합을 공부한다.(순열은 아직 뭔지 모름)

조합 문제를 풀었다.


분자식이 나오는데, 분자식이 어떤건지 몰라서 도움을 많이 받았다.

문제는 M1 + M2 = M3 가 균형이 맞으면 된다.

원자번호로 균형을 맞추는게 아니라 각 원자의 갯수를 맞춰야 된다.


아이디어만 있으면 쉽게 풀 수 있는 문제.


import java.io.*;
import java.util.*;
/**
* BOJ 1907 탄소 화합물
* https://gist.github.com/KSH-code/a53903cfa3d3ed0a0391637676d058a5
*/
class Main{
private static int q[][] = new int[3][3];
private static int result[] = new int[3];
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
String M123[] = s.split("\\+");
String M1 = M123[0];
String M23[] = M123[1].split("=");
String M2 = M23[0];
String M3 = M23[1];
Arrays.fill(result, 1);
divide(M1, 0, 0);
divide(M2, 0, 1);
divide(M3, 0, 2);
for(int i = 1; i<=10; i++){
for(int k = 1; k<= 10; k++){
for(int j = 1; j<= 10; j++){
int C,H,O;
C = j * q[1][0] + k * q[0][0];
H = j * q[1][1] + k * q[0][1];
O = j * q[1][2] + k * q[0][2];
int CC,HH,OO;
CC = i * q[2][0];
HH = i * q[2][1];
OO = i * q[2][2];
if(C == CC){
if(H == HH){
if(O == OO){
System.out.println(k + " " + j + " " + i);
return;
}
}
}
}
}
}
}
private static void divide(String s, int idx, int midx){
if(idx >= s.length())
return;
switch (s.charAt(idx)) {
case 'C':
q[midx][0] += getCount(s, idx+1);
break;
case 'H':
q[midx][1] += getCount(s, idx+1);
break;
case 'O':
q[midx][2] += getCount(s, idx+1);
break;
default:
break;
}
divide(s, idx + 1, midx);
}
private static int getCount(String s, int idx){
if(idx >= s.length()){
return 1;
}else{
if(s.charAt(idx) >= '2' && s.charAt(idx) <= '9'){
return s.charAt(idx) - 48;
}else{
return 1;
}
}
}
}
view raw Main.java hosted with ❤ by GitHub


+ Recent posts