[알고리즘] 문제풀이 연습

[0706 복습] 알골 연습문제 90제 : 6~10번

ddgoori 2019. 7. 6. 23:48

알골 연습문제 90제 : 6~10번

6번 - 숫자만 추출

 

문자와 숫자가 섞여있는 문자열이 주어지면 그 중 숫자만 추출하여 그 순서대로 자연수를 만 듭니다. 만들어진 자연수와 그 자연수의 약수 개수를 출력합니다. 만약 “t0e0a1c2her”에서 숫자만 추출하면 0, 0, 1, 2이고 이것을 자연수를 만들면 12가 됩니 다. 즉 첫 자리 0은 자연수화 할 때 무시합니다.  출력은 12를 출력하고, 다음 줄에 12의 약 수의 개수를 출력하면 됩니다. 추출하여 만들어지는 자연수는 100,000,000을 넘지 않습니다.
▣ 입력설명 첫 줄에 숫자가 썩인 문자열이 주어집니다. 문자열의 길이는 50을 넘지 않습니다.
▣ 출력설명 첫 줄에 자연수를 출력하고, 두 번째 줄에 약수의 개수를 출력합니

 

* 문자 배열 끝에는 '\0'이 들어가 있다.

* 아스키 코드 이용하면 알파벳 대문자 소문자 구할수 있다.

* 문자형 숫자인지 숫자형 숫자인지 구분해야한다.

- 문자형 숫자 -> 숫자형 숫자 변형시 -48

 

// 6 숫자만 추출 - 아마존 인터뷰 문제

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {

	char arr[50];
	int res = 0;

	scanf("%s", &arr);
	 
	for (int i = 0; arr[i] != 0; i++) { 
		if (arr[i] >= 48 && arr[i] < 58) { //아스키코드
			res = res * 10 + (arr[i] - 48); //문자형 숫자를 숫자형으로
		}
	}

	printf("%d\n", res);
	
	int count = 0;

	for (int i = 1; i <= res; i++) { //약수구하기
		if (res % i == 0) count++;
	}

	printf("%d\n", count);
	return 0;

}

 

 

 

7번 - 영어단어 복구

 

현수의 컴퓨터가 바이러스에 걸려 영어단어가 뛰어쓰기와 대소문자가 혼합되어 표현된다. 예를 들면 아름다운 이란 뜻을 가지고 있는 beautiful 단어가 “bE    au T I fu   L” 과 같이 컴퓨터에 표시되고 있습니다. 위와 같이 에러로 표시되는 영어단어를 원래의 표현대로 공백을 제거하고 소문자화 시켜 출력하는 프로그램을 작성하세요.
▣ 입력설명 첫 줄에 바이러스에 걸린 영어단어가 주어진다. 바이러스에 걸린 영어단어의 길이(공백포함)는 100을 넘지 않는다. 문자사이의 공백은 연속적으로 존재할 수 있습니다. 입력은 알파벳과 공 백만 주어집니다.
▣ 출력설명 첫 줄에 소문자로 된 정상적인 영어단어를 출력한다.

 

* 띄어쓰기가 연속으로 있는 것까지 읽어올 때는 scanf의 %s가 아니라,

gets(a); <-를 사용한다! 

* 공백이 아닌 것만 뽑아내는 조건문 if(a[i] != ' ')

* char a[100] 의 원소 중 일부를 char b[100]에 복사할 시에는 b배열 마지막에 

b[p] = '\0' 을 꼭 넣어준다. 마지막 원소라는 의미를 넣어줘야 깔끔하게 뽑힌다.

* 대문자에서 소문자 만들 때는 아스키코드로 +32만 더해주면 된다.

 

// 7번 - 영어단어 복구

#include <stdio.h>
#include <iostream>

int main() {

	char a[101];
	char b[101];

	gets_s(a);
	int j = 0;
	for (int i = 0; a[i] != '\0'; i++) {
		if (a[i] != ' ') {
			if (a[i] >= 65 && a[i] <= 90) {
				b[j++] = a[i] + 32;
				//주의! b[i] 아님! 조건문 될때만 들어오기때문에 iterator새로 생성 필요
			}
			else {
				b[j++] = a[i];
			}
		} 
	}
	//b배열 마지막에 '\0' 반드시 삽입해야 이상한 값 안나옴
	b[j] = '\0';
	printf("%s", b); //%s 이용하면 b배열 한번에 다 출력됨
	return 0;


}

 

 

 

8번 - 올바른 괄호

 

괄호가 입력되면 올바른 괄호이면 “YES", 올바르지 않으면 ”NO"를 출력합니다. (())() 이것은 괄호의 쌍이 올바르게 위치하는 거지만, (()()))은 올바른 괄호가 아니다.
▣ 입력설명 첫 번째 줄에 괄호 문자열이 입력됩니다. 문자열의 최대 길이는 30이다. 
▣ 출력설명 첫 번째 줄에 YES, NO를 출력한다.

 

* 원래는 스택으로 푸는 것이지만 약간의 꼼수를 부려서 풀 수 있다.

* 단 조건을 확인 잘 해야한다. ex) (()))( 같은 경우도 틀린 괄호이다. <-예외 처리해줘야 함

 

// 8번 문제
// 원래는 스택으로 풀면 좋지만 잔꾀를 이용해서도 가능ㅋ
 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {

	char a[31];
	int count = 0;

	scanf("%s", &a);

	for (int i = 0; a[i] != '\0'; i++) {
		if (a[i] == '(') count++;
		else count--;

		if (count<0)
		break;
	}

	if (count == 0) printf("YES");
	else printf("NO");

	return 0;

}

 

 

 

9번 - 모두의 약수

 

자연수 N이 입력되면 1부터 N까지의 각 숫자들의 약수의 개수를 출력하는 프로그램을 작성하 세요. 만약 N이 8이 입력된다면 1(1개), 2(2개), 3(2개), 4(3개), 5(2개), 6(4개), 7(2개), 8(4 개) 와 같이 각 숫자의 약수의 개수가 구해집니다. 출력은 다음과 같이 1부터 차례대로 약수의 개수만 출력하면 됩니다. 1 2 2 3 2 4 2 4 와 같이 출력한다.
▣ 입력설명 첫 번째 줄에 자연수 N(5<=N<=50,000)가 주어진다.
▣ 출력설명 첫 번째 줄에 1부터 N까지 약수의 개수를 순서대로 출력한다.

 

* 2중 for문을 쓸 시에 시간복잡도가 N^2까지 가서 N이 큰 숫자일 시에 타임아웃이 되버리는 사태가 발생한다.

* 역발상으로 모든 숫자의 약수가 몇개인지 구하는 것이 아니라, 배수를 찾다가 나오면 count++하는 방법 사용한다.

 

 // 9번 - 모두의 약수 구하기
// 각각의 약수의 갯수를 찾는게 아니라
// 각 숫자의 배수를 찾아 cnt++하여 갯수를 구한다

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int cnt[50001] = {0,};

int main() {

	int n;
	scanf("%d", &n);
	
	for (int i = 1; i <= n; i++) {
		//j 가 i부터 시작하여 i의 배수로 커진다는 것이 중요
		for (int j = i; j <= n; j += i) { //j = j+i : 역으로 i의 배수를 찾음
			cnt[j]++;
		}
	}
	for (int i = 1; i <= n; i++) {
		printf("%d ", cnt[i]);
	}
	return 0;
}

 

 

 

10번 - 자릿수의 합

 

N개의 자연수가 입력되면 각 자연수의 자릿수의 합을 구하고, 그 합이 최대인 자연수를 출력 하는 프로그램을 작성하세요. 각 자연수의 자릿수의 합을 구하는 함수를 int digit_sum(int x)를 꼭 작성해서 프로그래밍 하세요.
▣ 입력설명 첫 줄에 자연수의 개수 N(3<=N<=100)이 주어지고, 그 다음 줄에 N개의 자연수가 주어진다. 각 자연수의 크기는 10,000,000를 넘지 않는다.
▣ 출력설명 자릿수의 합이 최대인 자연수를 출력한다.

 

* 포인트는 각 자릿수의 합 중아 가장 큰 것을 출력하는 것이지만, 가장 큰 합의 값이 아닌 원래의 수num을 구해야한다.

* 연결된 수를 각자릿수로 분해하는 방법도 잘 봐두자

 

// 10번 - 자릿수의 합

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int digit_sum(int x) {
	
	int sum = 0, temp;
	
	while (x > 0) {
		temp = x % 10;
		sum += temp;
		x = x / 10;
	}

	return sum;
}

int main() {

	int n, num=0, sum, max= -2147000000, res;
	scanf("%d", &n);

	for (int i = 1; i <= n; i++) {
		scanf("%d", &num);
		sum = digit_sum(num);
		if (sum > max) {
			max = sum;
			res = num;
		}
	}

	printf("%d", res);
	return 0;
}

 

점점 뒤로 갈수록 어려워진다!

정신 바짝 차리자....!!!