저번에 못풀었던 문제를 다시 풀었어요.

분할 정복 형식으로 풀고, 재귀 함수를 이용하였습니다!!


문제

한수는 2차원 배열 (항상 2^N * 2^N 크기이다)을 Z모양으로 탐색하려고 한다. 예를 들어, 2*2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.

만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.

다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.

N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.

다음 그림은 N=3일 때의 예이다.

입력

첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다

출력

첫째 줄에 문제의 정답을 출력한다.


예제 입력 

2 3 1

예제 출력 

11

 

출처: https://www.acmicpc.net/problem/1074


아래의 소스를 참고하세욧!!

오랜만에 비트 shift도 썼네... 헷... 뿌듯합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
 
int n, r, c;
int go(int length, int x, int y)
{
    //length:행(열)의 개수, x: current row, y: current cloumn
    //재귀를 멈추기 위한 제약식
    if (length == 1return 0;
    //bound: 사분면의 경계
    int bound = length >> 1;
    //사분면 최소값을 더해주기 위한 변수
    int min = bound * bound;
 
    if(x < bound && y < bound) return go (bound, x, y);
    else if (x < bound && y >= bound) return min + go(bound, x, y - bound);
    else if (x >= bound && y < bound) return min * 2 + go(bound, x - bound, y);
    return min * 3 + go(bound, x - bound, y - bound);
}
int main()
{
        scanf("%d%d%d"&n,&r,&c);
        printf("%d", go(1 << n, r, c));
}
cs


'알고이즘 > 문제를 막풀어' 카테고리의 다른 글

[boj]1004 어린왕자  (0) 2017.12.04
[boj] no.1003 피보나치  (0) 2017.12.01
[boj] no.2775 부녀회장이 될테야  (0) 2017.11.29
[boj] no.1074 z  (2) 2017.11.28
[boj] no.1002 터렛  (1) 2017.11.27

오늘의 문제는 제목도 짱 귀여운!!!! 부녀회장이 될테얌!




문제

평소 반상회에 참석하는 것을 좋아하는 주희는 이번 기회에 부녀회장이 되고 싶어 각 층의 사람들을 불러 모아 반상회를 주최하려고 한다.

이 아파트에 거주를 하려면 조건이 있는데, “a 층의 b 호에 살려면 자신의 아래(a-1)층에 1호부터 b 호까지 사람들의 수의 합만큼 사람들을 

데려와 살아야한다” 는 계약 조항을 꼭 지키고 들어와야 한다.

아파트에 비어있는 집은 없고 모든 거주민들이 이 계약 조건을 지키고 왔다고 가정 했을 때, 주어지는 양의 정수 k와 n에 대해 k층에 n호

에는 몇 명이 살고 있나를 출력하라. 단, 아파트에는 0층부터 있고 각층에는 1호부터 있으며, 0층에 i호에는 i명이 산다.

입력

첫 번째 줄에 Test case의 수 T가 주어진다. 그리고 각각의 케이스마다 입력으로 첫 번째 줄에 정수 k, 두 번째 줄에 정수 n이 주어진다.

 (1 <= k <= 14, 1 <= n <= 14)

출력

각각의 Test case에 대해서 해당 집에 거주민 수를 출력하라.

예제 입력 

2
1
3
2
3

예제 출력 

6
10










출처: https://www.acmicpc.net/problem/2775


문제를 푸는데에 동적할당을 사용하였다.

백준에서는 ... 런타임 오류가 뜬다... 

ㅠㅜ 고민해봐야겠댜... ㅠㅠ


<풀이>

다이나믹 프로그래밍을 사용하면 된다.

큰 문제를 작은 문제로 나눠서, 구한 작은 값들을 저장하여 큰 값을 구하는 것이다.

점화식은 아래의 코드에서 확인하세요!



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
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
    int T,k,n;//T:test case,k:floor,n:room
    int i,j;
    int **ptr;//동적할당 포인터
    scanf("%d",&T);
    while(T){
        scanf("%d %d",&k,&n);
        //2차원 배열 동적할당
        ptr = (int**)malloc(sizeof(int*)*(k+1));
        for(i=0;i<=n;i++)   ptr[i] =(int*)malloc(sizeof(int)*(n+1));
        //0F의 사람수 자동입력
        for(i=0;i<=n;i++)   ptr[0][i] = i;
        //매층의 0호는 존재하지 않는다.
        for(i=0;i<=k;i++)   ptr[i][0= 0;
        //점화식
        for(i=1;i<=k;i++){
            for(j=1;j<=n;j++)   ptr[i][j] = ptr[i-1][j] + ptr[i][j-1];
        }
        printf("%d\n",ptr[k][n]);
        T--;
        //포인터 끊기
        if(T) ptr = NULL;
    }
    for(i=0;i<=n;i++free(ptr[i]);
    free(ptr);
    return 0;
}
cs








'알고이즘 > 문제를 막풀어' 카테고리의 다른 글

[boj] no.1003 피보나치  (0) 2017.12.01
[boj] no.1074 Z (2)  (0) 2017.11.30
[boj] no.1074 z  (2) 2017.11.28
[boj] no.1002 터렛  (1) 2017.11.27
[boj] no.2448 별찍기!!  (0) 2017.11.23

오늘의 문제는 햄숙이와 함께 시도했다.....

그러나 다 풀지 못했돠... ㅠㅠ 

일찍 일찍 시작하자.. ㅠㅠ


문제

한수는 2차원 배열 (항상 2^N * 2^N 크기이다)을 Z모양으로 탐색하려고 한다. 예를 들어, 2*2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.

만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.

다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.

N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.

다음 그림은 N=3일 때의 예이다.

입력

첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다

출력

첫째 줄에 문제의 정답을 출력한다.


예제 입력 

2 3 1

예제 출력 

11

 

출처: https://www.acmicpc.net/problem/1074


오늘은 재귀함수 문제를 풀어볼라고 시도했는데, 알고리즘을 짜는데 막히는 부분이 있었습니다.. ㅠㅠ 

아무래도 생각을 길게 안하고 풀려고 하다가 보니 그런게 아닐까나.... 일단 오늘까지 한 부분은 아래와 같습니다.

마지막 결과를 어떻게 도출할 지만 함수에 포함하고 재귀함수를 불러오는 부분을 어떻게 짤지는 좀더 생각해 봐야겠습니다.


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
#include <stdio.h>
int bound=0;
 
int main(int argc, char const *argv[]) {
  int N,r,c,arr,num,bound;
  int **ptr;
  int i,j;
 
  scanf("%d"&N);
  ptr = (int**)malloc(sizeof(int*)*N);
  for (i = 0; i < N; i++) {
    ptr[i] = (int*)malloc(sizeof(int)*N);
  }
  
 
 
 
  for (i = 0; i < N; i++) {
    free(ptr[i]);
  }
  free(ptr);
  
  return 0;
}
int cal(int N){
  //마지막 결과 값 도출
  if (N==1) {
    if (r<bound&&c<bound) {
      num = bound;
    } else if (r<bound&&c>=bound) {
      num = bound + 1;
    } else if (r>=bound&&c<bound) {
      num = bound + 2;
    } else {
      num = bound + 3;
    }
  } else { //재귀함수
    bound = 
  }
  
}
cs


1DP를 아침에 꼭 시작하겠다는 마음을 다지는 하루.... 

인생 올바르게 살아야 안되긋나... 싶네요.... 퓹퓹 ㅠㅠ

'알고이즘 > 문제를 막풀어' 카테고리의 다른 글

[boj] no.1074 Z (2)  (0) 2017.11.30
[boj] no.2775 부녀회장이 될테야  (0) 2017.11.29
[boj] no.1002 터렛  (1) 2017.11.27
[boj] no.2448 별찍기!!  (0) 2017.11.23
[boj] no.1152 단어의 개수  (0) 2017.11.22

+ Recent posts