728x90
1. 코드 refactoring
1. 12891번 - DNA 비밀번호
import sys
s, p = map(int, sys.stdin.readline().split())
dna = list(sys.stdin.readline().strip())
# A, C, G, T
esssential = list(map(int, sys.stdin.readline().split()))
def remove(st) :
global a, c, g, t
if dna[st] == 'A' :
a -= 1
elif dna[st] == 'C' :
c -= 1
elif dna[st] == 'G' :
g -= 1
elif dna[st] == 'T' :
t -= 1
return 0
def add(e) :
global a, c, g, t
if dna[e] == 'A' :
a += 1
elif dna[e] == 'C' :
c += 1
elif dna[e] == 'G' :
g += 1
elif dna[e] == 'T' :
t += 1
return 0
start = 0
end = p-1
count = 0
# 현재 부분 문자열
current = dna[0:p]
# 각각의 원소 포함 개수
a = current.count("A")
c = current.count("C")
g = current.count("G")
t = current.count("T")
while end < s :
# 만약에 모든 원소들의 조건을 충족했다면
if a >= esssential[0] and c >= esssential[1] and g >= esssential[2] and t >= esssential[3] :
count += 1
remove(start)
start += 1
end += 1
if end == s :
break
add(end)
print(count)
< 원래 코드 > https://soo-note.tistory.com/61
생각해보니 deque로 저장할 필요가 없었다.
문제 풀이에 중요한 것은 각각의 문자들을 몇 개 가지고 있냐이다.
그래서 현재 문자열을 저장하는 부분을 빼고 다시 작성했다.
2. 문제 풀이
1. 1890번 - 점프
import sys
N = int(sys.stdin.readline())
game = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
dp = [[0] * N for _ in range(N)]
dp[0][0] = 1
for i in range(N) :
for j in range(N) :
if i == N-1 and j == N-1 :
break
if j + game[i][j] < N : # 오른쪽
dp[i][j + game[i][j]] += dp[i][j]
if i + game[i][j] < N : # 아래쪽
dp[i + game[i][j]][j] += dp[i][j]
print(dp[N-1][N-1])
2. 1520번 - 내리막 길
import sys
M, N = map(int, sys.stdin.readline().split())
graph = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
visited = [[-1] * N for _ in range(M)]
def dfs(x, y) :
if x == M-1 and y == N-1 :
return 1
# 방문하지 않았을 경우
# 즉, 계산을 아직 하지 않았을 경우 계산하기
if visited[x][y] == -1 :
visited[x][y] = 0
for i in range(4) :
nx, ny = x + dx[i], y + dy[i]
if 0 <= nx < M and 0 <= ny < N and graph[nx][ny] < graph[x][y] :
visited[x][y] += dfs(nx, ny)
return visited[x][y]
print(dfs(0, 0))
3. 풀어 볼 문제 : 1379번 - 강의실2
3. C언어
1. pointer
특정한 데이터가 저장된 (시작)주소값을 보관하는 변수
int a = 10;
int *p = &a;
- (포인터에 주소값이 저장되는 데이터형)* (포인터 이름)
- 시작 주소부터 주어진 데이터형 크기만큼을 읽어올 수 있도록 지정해준다.
- & 연산자 : 피연산자의 주소값을 가져온다.
- * 연산자 : 해당 주소값에 대응되는 데이터를 가져온다.
- 즉, *p는 a와 같다.
- p + 3 은 p의 주소값에 3*4 = 12 가 더해진다.
- 4가 곱해서 더해지는 이유는 int형이 4byte이기 때문이다.
- const : 상수 포인터 = 값이 절대로 바뀌면 안된다.
const int *p = &a;
- 포인터에 적용하면 포인터가 가리키는 값은 변하면 안된다.
- 그러므로 p = &b; 는 오류 발생
- 그러나 *p = 5; 는 가능
- 즉, p가 가리키는 값은 변경하면 안된다 = 저장된 주소값이 바뀌면 안된다.
- p 가 가리키는 주소값이 저장하고 있는 내용은 변경할 수 있다.
- 배열
- 배열의 이름 = 배열의 첫번째 주소값 / 그러나 배열의 이름이 배열의 포인터는 아니다!
#include <stdio.h>
int main() {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *p;
p = &arr[0];
printf("arr[3] = %d , *(p + 3) = %d \n", arr[3], *(p + 3));
return 0;
}
- 배열의 첫번째 요소의 주소값을 가지는 포인터 p 로 배열의 원소에 접근할 수 있다.
- *(p + 3) = arr[3] = 4
- 위와 같이 포인터에 인덱스 만큼 더해주고 그 주소 안에 있는 값을 가져오면 똑같다.
- 2차원 배열일 경우
- int (*p)[2] = arr : 크기가 2인 배열을 가리키는 포인터
- 포인터 배열 : 배열의 각 원소들이 모두 포인터인 배열 → 각 원소들이 다른 일차원 배열들을 가리킬 수 있다.
- 이차원 배열에서 배열의 이름이 첫번째 행을 가리킨다. = a[0] → (a[0][0], a[0][1])
- 위에서 포인터 p는 길이가 2인 intg형 배열을 가리키므로 p+1은 주소값에 8을 더해줘야 한다.
< 2차원 배열 포인터 참고 >
🔗 https://wonit.tistory.com/527
2. Struct (구조체)
각 멤버(member)의 타입이 제각각인 배열
즉, 여러 자료형의 변수들을 그룹으로 묶어서 하나의 자료형으로 선언하여 사용
#include <stdio.h>
struct Human {
int age; /* 나이 */
int height; /* 키 */
int weight; /* 몸무게 */
}; /* ; 붙이는 것 주의하세요 */
void main() {
struct Human h;
struct Human *hp = &h;
h.age = 20;
hp->height = 170;
hp->weight = 50;
printf("%d\n", hp->age);
printf("%d\n", h.height);
printf("%d\n", h.weight);
}
- 구조체의 정의에서 변수를 초기화할 수 없다.
- 점 연산자(.) : 구조체 변수의 데이터 항목을 지정
- 화살표 연산자(->) : 구조체형 포인터가 가리키는 구조체 변수의 데이터 항목 지정
3. enum (열거형)
각 데이터에 수를 대응시킬 때 사용
enum { MALE, FEMALE }
- 위와 같이 선언했을 경우 MALE = 0, FEMALE = 1로 나타낼 수 있다.
- 원하는 숫자가 있으면 MALE=3 이라고 선언해주면 FEMALE = 4가 된다.
4. 동적 메모리 할당
컴퓨터 프로그래밍에서 실행 시간 동안 사용할 메모리 공간을 할당하는 것
1. malloc : memory allocation
: 동적으로 메모리를 할당하는 함수로 힙영역에 메모리를 할당한다.
- 장점: 상황에 따라 원하는 크기만큼의 메모리가 할당되므로 경제적이며, 이미 할당된 메모리라도 언제든지 크기를 조절할 수 있다.
- 단점: 더 이상 사용하지 않을 때 명시적으로 메모리를 해제해 주어야 한다.
score = (int *)malloc(n * sizeof(int));
/* int score[n]과 같이 만든 것이다. */
- n개의 int 자료형의 크기만큼 메모리를 할당한다.
- <stdlib.h> 헤더 파일을 포함시켜줘야 한다.
- malloc 함수 호출시 할당하고자 하는 메모리의 크기를 바이트 단위로 전달
- return 할당한 메모리의 첫번째 바이트 주소
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int student;
int i, input;
int *score;
int sum = 0;
//학생 수 입력받기
printf("학생 수는? : ");
scanf("%d", &student);
//학생수만큼의 배열 생성하기
score = (int *)malloc(student * sizeof(int));
for (i = 0; i < student; i++) {
printf("학생 %d 의 점수 : ", i);
scanf("%d", &input);
score[i] = input;
sum += score[i];
}
printf("전체 학생의 평균 점수 : %d \n", sum / student);
// 힙 영역에 할당된 메모리를 해제하는 함수
free(score);
return 0;
}
< 동적 메모리 할당 참고 >
🔗 https://dsnight.tistory.com/51
🔗 https://ko.wikipedia.org/wiki/동적_메모리_할당
앞으로도 C언어 공부
https://modoocode.com/231
728x90
'KraftonJungle2기 > Today I Learned' 카테고리의 다른 글
[TIL] Red-Black Tree 개념(삽입/삭제) + 기계 수준 표현(스택)2 (0) | 2023.05.06 |
---|---|
[TIL] LinkedList & AVL Tree (with C) (1) | 2023.05.05 |
[TIL] 문제 풀이 연습 - two point (with python) (1) | 2023.05.03 |
[TIL] 동적 프로그래밍 문제 풀이3 (0) | 2023.05.02 |
[TIL] 그리디 문제 풀이 + 기계 수준 표현1 (0) | 2023.05.01 |