Home 코테 스터디 1-10번 문제 풀이
Post
Cancel

코테 스터디 1-10번 문제 풀이

코테 스터디 1-10번 문제 풀이

[0] 진약수

진약수 갯수 구하기

  • 진약수 : 자기 자신을 뺀 약수들

[1] 최대, 최소값

min, max 값 구할 때 팁

int형의 가장 작은 수 : -214000000

int형의 가장 큰 수: 214000000

1
2
3
4
5
6
7
8
9
10
11
//최소값, 최대값 구하기

	for(i=1; i<=n; i++){
		cin>>a; //cin : enter 치거나 space로 구분하거나 같음  
		if(a>max){
			max=a;
		}
		if(a<min){
			min=a;
		}
	}

[2] freopen()

input값들을 txt파일에 미리 저장해놓고 쓰는 법

freopen(”[텍스트파일명.txt]”,”rt”, stdin);

  • 복잡한 input값들을 미리 정해놓고 긁어다가 활용할 수 있다
  • 파일을 읽어와서 stdin 표준입력에 대한 포인터로 전달한다

[3] cin과 scanf

cin 과 scanf

  1. cin : enter을 치거나 space로 구분하는 것이랑 같음!
  2. scanf 도 같음!

= ✨ 한줄로 입력 값들을 쭉 칠 수 있음!

[4] 주민등록번호로 나이 계산

주민 등록 번호로 나이 계산하기

[1] 나이 계산 기본

[뒷자리 첫번째 글자]

  • 여자
    • 2 : ~1999년생
    • 4 : 2000년생 ~
  • 남자
    • 1 : ~1999년생
    • 3 : 2000년생 ~

[2] 아스키코드와 숫자 🔥

주민등록의 경우에는 문자열로 받아서 숫자로 계산해야 한다

  • 암기하면 편하다
문자아스키코드
‘0’48

[3] 나이 계산 알고리즘

  1. if [1] ~1999년생과 [2] 2000년생 ~ 으로 나눈다
  2. year 출생 년도를 만든다 (98xxxx → 1998)
  3. age 현재 년도 기준 - 출생년도 + 1 을 하여 나이를 구한다
1
2
3
4
5
6
7
8
9
10
11
12
	//[1] 나이 계산하기
	//1)19xx년생 일때 2)20xx년생 일때로 구분하여 나이를 구한다

	//** 아스키코드 48 = '0' **
	if(a[7]=='1' || a[7]=='2')
		year = 1900 + (a[0]-48)*10 + (a[1]-48);

	else
		year =  2000 + (a[0]-48)*10 + (a[1]-48);

	age = 2022-year+1; //연도 기준 2022

[5] 문자열 관련 1

[1]

문자열 구하는 함수 쓰지 않고 반복문 돌리기

  • 문자열 끝에는 ‘\0’ : NULL 문자가 들어감 🌟 !
    • 이를 이용하여 반복문을 돌리자
1
2
3
4
	//a[i] != '\0' 의 의미: 문자열의 끝을 알리는 문자 = \0
	for(i =0; a[i] != '\0';i++){

	}

[2]

문자열 아스키 코드로 숫자 구분하기

48 = ‘0’ ~ 57 = ‘9’

숫자 구하기

‘문자’ - 48

1
2
3
4
//아스키 코드로 0부터 9까지의 숫자 문자
if(a[i] >= 48 && a[i] <= 57)
{  
}

[6] 문자열 관련 2

[1]

대문자에서 소문자 구하기

대문자 문자 + 32

[2]

공백 (스페이스 입력)을 포함하여 문자열 읽기

  • scanf 나 cin 을 사용하면 공백 (스페이스)를 입력 (엔터처리)하여 값이 들어간다

gets([주소]) 를 사용하면, 공백을 포함하여 한줄 통으로 문자열 값으로 쳐진다

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 <iostream>

//영어 단어 복구
// 문자열의 공백을 제거하고, 소문자로 변경시켜 출력하라
	//bE    au   T   I fu   L => beautiful 로 바꿔서 출력!

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	char a[101], b[101];
	int i, pos=0;

	//* 중요 함수 ! *
	gets(a); //공백, 스페이스 상관없이 한줄 읽어버림

	for(i =0; a[i] != '\0'; i++){
		if(a[i] != ' '){ //[1] 공백이 아닐 때
			if(a[i] >= 65 && a[i] <= 90){
				b[pos++] = a[i] + 32;
				//아스키코드 상 대문자에서 소문자로 변하기 +32를 하면 소문자로 변함
			}
			else b[pos++] = a[i];
		}
	}
	b[pos] = '\0';
	printf("%s\n",b);

	return 0;
}

[7] 스택 안 쓰고, 괄호 검사하기

[1]

괄호 검사하기 스택 안 쓰고 풀기 꼼수!

  1. 괄호를 if 문으로 각각 여는괄호 +1, 닫는괄호 -1로 설정한다
  2. 거짓 증상
    1. 닫는 괄호가 더 많은 경우 위 값의 합이 중간에 음수가 나온다
      • 사유 : 닫는 괄호가 제대로 나오면 무조건 0이다
    2. 반복문으로 다 검사 후 합 값이 음수이다
  3. 참 증상
    1. 모두 검사했지만 위 경우들에 해당하지 않는다
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
#include <iostream>

//올바른 괄호
//괄호가 입력되는데, 올바르면 YES, 올바르지 않으면 NO 출력
//여는 괄호가 있는데 닫는 괄호가 없으면 올바르지 않은 것임
// [스택 미사용 방법]

// 괄호 당 1 로 값을 할당하고, 닫는 괄호는 -1 음수로 할당한다 => 최종 값이 0 이 아니면 거짓!  

int main(int argc, char** argv) {
	char a[101];
	int i, cnt = 0;

	scanf("%s", &a);

	for(i =0; a[i] != '\0'; i++){
		if(a[i]=='('){
			cnt += 1;
		}
		else if(a[i]==')'){
			cnt -= 1;
		}

		if(cnt <0) break; //중간에 음수가 나오는 경우는 닫는 괄호가 더 많은 경우이므로 무조건 거짓!

	}

	if(cnt == 0){
		printf("YES\n");
	}
	else{
		printf("NO\n");
	}
	return 0;
}

[8] 빡센 약수 갯수 구하기

N까지의 모든 수의 약수 갯수를 출력하는 문제

배수를 이용하여 배수부터 검사하는 방법을 사용하자

[1]

정석 (빡센 문제에서 타임리미트) 나오는 약수 구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
	//[1] ================
	int cnt =0;
	//타임리미트 풀이
	for(i =1; i<=n; i++){
		cnt=0;
		for(j=1; j<=i; j++){
			if(i%j==0){
				cnt++;
			}
		}
		printf("%d ",cnt);		
	}

[2] 배수 검사로 약수 갯수 구하기

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
#include <iostream>

//모두의 약수
//*!! 타임리미트 존재 !!*
//N을 입력하면 1부터 N까지의 모든 수의 약수의 갯수가 출력되게 하라


int cnt[50001]; //n의 크기 제한이 <=50000까지 이므로 50001을 배열 길이로 설정
//전역 변수로 배열을 선언하면 값이 0으로 초기화가 된다 !!***
//지역 변수로 cnt를 할당하게 되면 값들이 0으로 초기화 되지 않아서 이상한 값이 나오고
//50001은 너무 큰 배열이라 스택에 할당하게 되면 값이 제대로 할당되지 않을 수가 있다

int main(int argc, char** argv) {
	int n,i,j;

	scanf("%i", &n);

	//[2] =================
	// i가 1일 시 cnt 결과 :  
	//cnt [1] [1] [1] [1] [1] [1] [1] [1] [1] ... [1]
	//배수로 약수를 구하는 풀이

	//int cnt[50001];
	for(i=1; i<=n; i++){
		for(j=i; j<=n; j=j+i){//i의 배수로 약수를 증가시키기
			cnt[j]++; //j는 i의 배수 이므로 약수 개수 1 추가됨 !
		}
		//printf("%d ",cnt[i]);
	}

	for(i=1; i<=n; i++){
		printf("%d ", cnt[i]);
	}



	return 0;
}

[9] 전역 변수 선언

  • 지역 변수 선언을 하면 문제가 틀리는 문제가 있다
  • 이유:
    1. 지역 변수는 선언만으로는 초기화가 안 된다
      1. ↔ 전역 변수 선언은 선언만으로 배열, 변수 값이 0으로 초기화 된다
    2. 지역 변수는 스택 영역에서 만들어지며, 이 공간이 충분히 크지 않기 때문에 들어가는 값이 너무 크면 이상한 값이 될 수가 있다 ⇒ 전역변수로 선언하자!
1
2
3
4
5
6
7
8
int cnt[50001]; //n의 크기 제한이 <=50000까지 이므로 50001을 배열 길이로 설정
//전역 변수로 배열을 선언하면 값이 0으로 초기화가 된다 !!***
//지역 변수로 cnt를 할당하게 되면 값들이 0으로 초기화 되지 않아서 이상한 값이 나오고
//50001은 너무 큰 배열이라 스택에 할당하게 되면 값이 제대로 할당되지 않을 수가 있다

int main(int argc, char** argv) {
	...
}

[10] 자릿수의 구하기

자릿수 구하기

  1. 어떤수 X를 10으로 나눈 나머지 = 제일 오른쪽 자릿수
  2. 어떤수 X를 10으로 나눈 몫 = 제일 오른쪽 자릿수를 뺀 수
    • 123 / 10 → 12
  3. 어떤수 X를 계속 10으로 나눠서 0이 나누면 다 나눈 것이다
    • 100 → (1) 100/10, (2) 10/10, (3) 1/10 = 0 : 다 나눈 것
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
     #include <iostream>
    
     //자릿수의 합
     //N개의 자연수가 입력 되면 각 자연수의 자릿수의 합을 구하고,
     //그 자릿수의 합이 최대인 자연수를 출력하라
     //자연수의 자릿수를 구하는 함수는 int digit_sum(int x) 를 작성하라
    
     //자릿수 구하기
     int digit_sum(int x){
     	int tmp, sum = 0 ;
    
     	//!!**중요**!!
     	//자릿수 구하기 (제일 오른쪽 자릿수 -> 왼쪽 자릿수를 더해가는 식)
     	while(x>0){
     		tmp = x%10; // 10으로 나눈 나머지 : 제일 끝자리 수 출력
     		x /= 10; // = 제일 끝자리를 뺀 수 ... 8ㅅ8
     		sum += tmp;
     	}
    
    
    
This post is licensed under CC BY 4.0 by the author.