검색결과 리스트
글
문제
옛날 옛적에 수학이 항상 큰 골칫거리였던 나라가 있었다. 이 나라의 국왕 김지민은 다음과 같은 문제를 내고 큰 상금을 걸었다.
길이가 N인 정수 배열 A와 B가 있다. 다음과 같이 함수 S를 정의하자.
S = A[0]*B[0] + ... + A[N-1]*B[N-1]
S의 값을 가장 작게 만들기 위해 A의 수를 재배열하자. 단, B에 있는 수는 재배열하면 안된다.
S의 최솟값을 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거나 같은 음이 아닌 정수이다.
출력
첫째 줄에 S의 최솟값을 출력한다.
예제 입력
예제 출력
한 쪽 배열을 오름차순으로 정렬하고
다른 한 쪽 배열을 내림차순으로 정렬하여 해결한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <iostream> using namespace std; int main() { int A[50], B[50]; int N; cin >> N; for ( int i=0;i<N;i++) { cin >> A[i]; } for ( int i=0;i<N;i++) { cin >> B[i]; } for ( int i=0;i<N;i++) { for ( int j=i+1;j<N;j++) { if (A[i] > A[j]) { swap(A[i], A[j]); } } } for ( int i=0;i<N;i++) { for ( int j=i+1;j<N;j++) { if (B[i] < B[j]) { swap(B[i], B[j]); } } } int sum=0; for ( int i=0;i<N;i++) { sum+=A[i]*B[i]; } cout << sum; } |
'Tip & Tech > 실전알고리즘' 카테고리의 다른 글
다리 놓기 (0) | 2013.09.23 |
---|---|
8진수 2진수 (0) | 2013.09.23 |
시작 (0) | 2013.09.23 |
트랙백
댓글
글
문제
재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 강이 흐르고 있다. 하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리를 짓기로 결심하였다. 강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다. 재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)
재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.) 재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다. 다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.
입력
입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.
출력
각 테스트 케이스에 대해 주어진 조건하에 다리를 지을 수 있는 경우의 수를 출력한다.
예제 입력
예제 출력
조합(combination)을 구하는 문제로 해석할 수 있다.
보통 고등학교에서 배우는 방법대로 조합을 구하다 보면 integer overflow가 발생할 수 있고
반복된 연산으로 Time-Limit 될 수 있다.
그렇기 때문에 배열을 이용하여 조합을 나타내 보기로 했다. (Dynamic Programming)
아래는 nCr을 나타낸 표이다.
nCr |
r = 1 |
2 |
3 |
4 |
5 |
6 |
n = 1 |
1 |
|
|
|
|
|
2 |
2 |
1 |
|
|
|
|
3 |
3 |
3 |
1 |
|
|
|
4 |
4 |
6 |
4 |
1 |
|
|
5 |
5 |
10 |
10 |
5 |
1 |
|
6 |
6 |
15 |
20 |
15 |
6 |
1 |
이 표를 배열로 나타낸다고 했을 때
arr[i][j] = arr[i-1][j-1] + arr[i][i-1][j] 라는 규칙을 찾을 수 있다.
이 규칙을 이용하여 표를 모두 채우고 시작한다면 조합을 쉽게 찾을 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> using namespace std; int main() { int dp[30][30] = {0,}; for ( int i=0;i<30;i++) { dp[0][i] = i+1; } for ( int i=1;i<30;i++) { for ( int j=1;j<30;j++) { dp[i][j] = dp[i-1][j-1] + dp[i][j-1]; } } int T, N, M; cin >> T; while (T--) { cin >> N >> M; cout << dp[N-1][M-1] << endl; } } |
문제 출처 : http://www.acmicpc.net/
'Tip & Tech > 실전알고리즘' 카테고리의 다른 글
보물 (0) | 2013.09.23 |
---|---|
8진수 2진수 (0) | 2013.09.23 |
시작 (0) | 2013.09.23 |
트랙백
댓글
글
문제
수가 8진수로 주어지면, 이를 2진수로 변환하는 프로그램을 작성하시오.
입력
첫째 줄에 수가 8진수로 주어진다. 주어지는 수의 길이는 333,334를 넘지 않는다.
출력
첫째 줄에 주어진 수를 2진수로 변환하여 출력한다. 수가 0인 경우를 제외하고는 반드시 1로 시작해야 한다.
예제 입력
예제 출력
8진수를 2진수로 바꾸라는 문제다.
복잡하게 문제를 해결하던 중 직관적이고 간단한 해법이 생각났다.
8진수, 0부터 7까지의 모든 경우의 수를 배열에 저장해보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> #include <cstring> using namespace std; int main() { char str[333335]; cin >> str; char dic1[8][4] = { "000" , "001" , "010" , "011" , "100" , "101" , "110" , "111" }; char dic2[8][4] = { "" , "1" , "10" , "11" , "100" , "101" , "110" , "111" }; cout << dic2[str[0]- '0' ]; int len = strlen (str); for ( int i=1;i<len;i++) { cout << dic1[str[i]- '0' ]; } } |
문제 출처 : http://www.acmicpc.net/
'Tip & Tech > 실전알고리즘' 카테고리의 다른 글
보물 (0) | 2013.09.23 |
---|---|
다리 놓기 (0) | 2013.09.23 |
시작 (0) | 2013.09.23 |
트랙백
댓글
글
우리 실전알고리즘은
ACM-ICPC (대학생 프로그래밍 경시대회) 형식의 문제를 풀어보고자 그룹 스터디를 시작하게 되었습니다.
교재는 따로 없으며 http://www.acmicpc.net/ 의 문제를 풀어갈 계획입니다.
'Tip & Tech > 실전알고리즘' 카테고리의 다른 글
보물 (0) | 2013.09.23 |
---|---|
다리 놓기 (0) | 2013.09.23 |
8진수 2진수 (0) | 2013.09.23 |
RECENT COMMENT