Hashing

 

 문제 설명

 

APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정의한다. 해시 함수는 무궁무진한 응용 분야를 갖는데, 대표적으로 자료의 저장과 탐색에 쓰인다.

이 문제에서는 여러분이 앞으로 유용하게 쓸 수 있는 해시 함수를 하나 가르쳐주고자 한다. 먼저, 편의상 입력으로 들어오는 문자열에는 영문 소문자(a, b, ..., z)로만 구성되어있다고 가정하자. 영어에는 총 26개의 알파벳이 존재하므로 a에는 1, b에는 2, c에는 3, ..., z에는 26으로 고유한 번호를 부여할 수 있다. 결과적으로 우리는 하나의 문자열을 수열로 변환할 수 있다. 예를 들어서 문자열 "abba"은 수열 1, 2, 2, 1로 나타낼 수 있다.

해시 값을 계산하기 위해서 우리는 문자열 혹은 수열을 하나의 정수로 치환하려고 한다. 간단하게는 수열의 값을 모두 더할 수도 있다. 해시 함수의 정의에서 유한한 범위의 출력을 가져야 한다고 했으니까 적당히 큰 수 M으로 나눠주자. 짜잔! 해시 함수가 완성되었다. 이를 수식으로 표현하면 아래와 같다.

해시 함수의 입력으로 들어올 수 있는 문자열의 종류는 무한하지만 출력 범위는 정해져있다. 다들 비둘기 집의 원리에 대해서는 한 번쯤 들어봤을 것이다. 그 원리에 의하면 서로 다른 문자열이더라도 동일한 해시 값을 가질 수 있다. 이를 해시 충돌이라고 하는데, 좋은 해시 함수는 최대한 충돌이 적게 일어나야 한다. 위에서 정의한 해시 함수는 알파벳의 순서만 바꿔도 충돌이 일어나기 때문에 나쁜 해시 함수이다. 그러니까 조금 더 개선해보자.

어떻게 하면 순서가 달라졌을때 출력값도 달라지게 할 수 있을까? 머리를 굴리면 수열의 각 항마다 고유한 계수를 부여하면 된다는 아이디어를 생각해볼 수 있다. 가장 대표적인 방법은 항의 번호에 해당하는 만큼 특정한 숫자를 거듭제곱해서 곱해준 다음 더하는 것이 있다. 이를 수식으로 표현하면 아래와 같다.

보통 r과 M은 서로소인 숫자로 정하는 것이 일반적이다. 우리가 직접 정하라고 하면 힘들테니까 r의 값은 26보다 큰 소수인 31로 하고 M의 값은 1234567891(놀랍게도 소수이다!!)로 하자.

이제 여러분이 할 일은 위 식을 통해 주어진 문자열의 해시 값을 계산하는 것이다. 그리고 이 함수는 간단해 보여도 자주 쓰이니까 기억해뒀다가 잘 써먹도록 하자.

 

 입력

 

첫 줄에는 문자열의 길이 L이 들어온다. 둘째 줄에는 영문 소문자로만 이루어진 문자열이 들어온다.

입력으로 주어지는 문자열은 모두 알파벳 소문자로만 구성되어 있다.

 

 출력

 

문제에서 주어진 해시함수와 입력으로 주어진 문자열을 사용해 계산한 해시 값을 정수로 출력한다.

 

 Python 코드

 

n = int(input()) #제시할 문자열의 길이를 입력받는다.
str_ = list(input()) #문자열을 입력받아 리스트에 대입한다.
res = 0 # 출력할 변수 res를 선언한다.

for i in range(n): # 문자열의 길이만큼 반복한다.
    res += ((ord(str_[i]) - 96) * (31 ** i))
# 리스트 내 각각의 요소들은 아스키코드값으로 변경 후 96을 빼면 
# a는 1, b는 2의 값을 지니게 된다.
# 계수가 31이고 문자열의 순서에 따라 지수가 높아지므로 이를 고려하여 식을 짜면 위와 같다.

print(res % 1234567891)
# 해시 함수의 정의에서 유한한 범위의 출력을 가져야 한다고 했으므로 M을 나누어 출력한다.

* 참고 링크 : https://velog.io/@cornflower_blue/%EB%B0%B1%EC%A4%80%ED%8C%8C%EC%9D%B4%EC%8D%AC-15829%EB%B2%88-Hashing-%ED%92%80%EC%9D%B4

# readline을 사용하기 위해 Import
from sys import stdin

# 첫 줄에는 문자열의 길이 L을 입력
# 1 <= L <= 50
# 정수형으로 변환합니다.
L = int(stdin.readline())

# 둘째 줄에는 영문 소문자로만 이루어진 문자열을 입력
# 맨 끝의 \n은 떼어준다.
string = stdin.readline().rstrip()

# 해시 값을 계산할 때 필요한 r, M의 값을 저장하는 변수를 선언
r = 31
M = 1234567891

# mod M을 구하기 전의 ai * r^i의 합계를 저장할 변수를 선언
ar_sum = 0

# 입력한 문자열에서 한 글자씩 반복
for idx in range(L):
    # 현재 글자의 고유 번호를 저장하는 변수를 선언
    ai = ord(string[idx]) -ord('a') +1

    #현재 글자의 ai * r^i 값을 ar_sum에 더해준다.
    ar_sum += ai * (r ** idx)

# 해시값인 ar_sum을 M으로 나눈 뒤의 나머지의 값을 출력
print(ar_sum % M)

 

 C++ 코드

 

#include <iostream> 
#include <string> 
using namespace std; 

const int MOD = 1234567891; 
const int MULTIPLY = 31; 

int main(void) { 
int L; 
cin >> L; 
string s; 
cin >> s; 

long long sum = 0; 
long long R = 1; 

for (int i = 0; i < s.length(); i++) { 
	sum = (sum + (s[i] - 'a' + 1) * R) % MOD; 
	R = (R*MULTIPLY) % MOD; 
} 

cout << sum << "\n"; 
return 0; 
}

* 참고 링크 : https://jaimemin.tistory.com/1445

 

 출처

 

https://www.acmicpc.net/problem/15829

전자레인지

 

 문제 설명

 

3개의 시간조절용 버튼 A B C가 달린 전자레인지가 있다. 각 버튼마다 일정한 시간이 지정되어 있어 해당 버튼을 한번 누를 때마다 그 시간이 동작시간에 더해진다. 버튼 A, B, C에 지정된 시간은 각각 5분, 1분, 10초이다.

냉동음식마다 전자레인지로 요리해야할 시간 T가 초단위로 표시되어 있다. 우리는 A, B, C 3개의 버튼을 적절히 눌러서 그 시간의 합이 정확히 T초가 되도록 해야 한다. 단 버튼 A, B, C를 누른 횟수의 합은 항상 최소가 되어야 한다. 이것을 최소버튼 조작이라고 한다. 

만일 요리시간이 100초라고 하면(T=100) B를 1번, C는 4번 누르면 된다. 이와 다르게 C를 10번 눌러도 100초가 되지만 이 경우 10번은 최소 횟수가 아니기 때문이 답이 될 수 없다. 이 경우 B 1번, C 4번, 총 5번이 최소버튼 조작이다. 그리고 T=234와 같이 3개의 버튼으로 시간을 정확히 맞출 수 없는 경우도 있다. 

여러분은 주어진 요리시간 T초를 맞추기 위한 최소버튼 조작 방법을 구하는 프로그램을 작성해야 한다. 

 

 입력

 

첫 번째 줄에는 요리시간 T(초)가 정수로 주어져 있으며 그 범위는 1 ≤ T ≤ 10,000 이다. 

 

 출력

 

여러분은 T초를 위한 최소버튼 조작의 A B C 횟수를 첫 줄에 차례대로 출력해야 한다. 각각의 횟수 사이에는 빈 칸을 둔다. 해당 버튼을 누르지 않는 경우에는 숫자 0을 출력해야한다. 만일 제시된 3개의 버튼으로 T초를 맞출 수 없으면 음수 -1을 첫 줄에 출력해야 한다. 

 

 Python 코드

 

T = int(input())                # 요리 시간 T를 int type으로 입력을 받는다.

button = [300, 60 ,10]          # 버튼 300, 60, 10을 리스트에 담아준다.

if T % 10 != 0:                 # 만약 T를 10으로 나누었을 때 나머지가 0이 아니면 -1 출력
    print(-1)
else:                           # 그게 아니라면
    for i in button:            # button 안에 있는 i 요소 반복
        print(T//i, end = " ")  # T를 i로 나누었을 때 몫을 띄어쓰기로 출력
        T = T % i               # T는 T를 i로 나누었을 때 몫으로 바꾼다.

 

* 참고 링크 : https://www.youtube.com/watch?v=FoTqNiXgd-0 

 

 C++ 코드

 

#include<iostream>
using namespace std;

int main() {
	
	// A : 300초, B : 60초, C : 10초
	int a, b, c = 0;
	int t;
	cin >> t;

	if (t % 10 != 0) cout << "-1";
	else {
		a = t / 300;
		b = (t % 300) / 60;
		c = ((t % 300) % 60) / 10;
		cout << a << " " << b << " " << c;
	}

	return 0;

}

* 참고 링크 : https://jeongminhee99.tistory.com/86

 

 출처

 

https://www.acmicpc.net/problem/10162

평균 구하기

 

 문제 설명

 

자연수 N이 주어진다. N을 이진수로 바꿔서 출력하는 프로그램을 작성하시오.

 

 입력

 

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 100,000,000,000,000)

 

 출력

 

N을 이진수로 바꿔서 출력한다. 이진수는 0으로 시작하면 안 된다.

 

 Python 코드

 

# 첫째 줄에 자연수 N을 입력하고 정수형으로 변환
N = int(input())

# N을 이진수로 변환하고 앞의 0b를 제외한 값을 저장
N = bin(N)[2:]

# 이진수로 변환한 결과 출력
print(N)

# print(bin(n)[2:])
# print(bin(int(input()))[2:])

* 참고 링크 : https://brightnightsky77.tistory.com/122

def trans(n):
    if (n<1):
        return '0'
    elif (n==1):
        return '1'
    if (n%2==0):
        return trans(int(n/2)) + '0'
    elif (n%2==1):
        return trans(int(n/2)) + '1'

n = int(input())
answer = trans(n)
print(answer)

* 참고 링크 : https://velog.io/@sxxzin/BaekjoonPython%EC%9D%B4%EC%A7%84%EC%88%98-%EB%B3%80%ED%99%98

https://my-coding-notes.tistory.com/137

 C++ 코드

 

#include <iostream>
using namespace std;

int facto(int n) {
	if (n <= 1)
		return 1;
	else
		return n * facto(n - 1);
}

int main() {
	int n;
	cin >> n;
	cout << facto(n) << '\n';
}

* 참고 링크 : https://codesyun.tistory.com/73

 출처

 

https://www.acmicpc.net/problem/10829

팩토리얼

 

 문제 설명

 

0보다 크거나 같은 정수 N이 주어진다. 이때, N!을 출력하는 프로그램을 작성하시오.

 

 입력

 

첫째 줄에 정수 N(0 ≤ N ≤ 12)이 주어진다.

 

 출력

 

첫째 줄에 N!을 출력한다.

 

 

 Python 코드

 

def factorial(n):
    result = 1
    if n > 0:
        result = n * factorial(n-1)
    return result

n = int(input())
print(factorial(n))

 

* 참고 링크 : https://ooyoung.tistory.com/114

 

 C++ 코드

 

#include <cstdio>

int factorial(int n)
{
    if(n <= 1)
        return 1;
    return n * factorial(n-1);
}

int main() {
    int num;
    scanf("%d",&num);
    printf("%d",factorial(num));
}

* 참고 링크 : https://cryptosalamander.tistory.com/36

 출처

 

https://www.acmicpc.net/problem/10872

Hashing

 

 문제 설명

 

APC에 온 것을 환영한다. 만약 여러분이 학교에서 자료구조를 수강했다면 해시 함수에 대해 배웠을 것이다. 해시 함수란 임의의 길이의 입력을 받아서 고정된 길이의 출력을 내보내는 함수로 정의한다. 해시 함수는 무궁무진한 응용 분야를 갖는데, 대표적으로 자료의 저장과 탐색에 쓰인다.

이 문제에서는 여러분이 앞으로 유용하게 쓸 수 있는 해시 함수를 하나 가르쳐주고자 한다. 먼저, 편의상 입력으로 들어오는 문자열에는 영문 소문자(a, b, ..., z)로만 구성되어있다고 가정하자. 영어에는 총 26개의 알파벳이 존재하므로 a에는 1, b에는 2, c에는 3, ..., z에는 26으로 고유한 번호를 부여할 수 있다. 결과적으로 우리는 하나의 문자열을 수열로 변환할 수 있다. 예를 들어서 문자열 "abba"은 수열 1, 2, 2, 1로 나타낼 수 있다.

해시 값을 계산하기 위해서 우리는 문자열 혹은 수열을 하나의 정수로 치환하려고 한다. 간단하게는 수열의 값을 모두 더할 수도 있다. 해시 함수의 정의에서 유한한 범위의 출력을 가져야 한다고 했으니까 적당히 큰 수 M으로 나눠주자. 짜잔! 해시 함수가 완성되었다. 이를 수식으로 표현하면 아래와 같다.

 H=∑i=0l−1aimodM

해시 함수의 입력으로 들어올 수 있는 문자열의 종류는 무한하지만 출력 범위는 정해져있다. 다들 비둘기 집의 원리에 대해서는 한 번쯤 들어봤을 것이다. 그 원리에 의하면 서로 다른 문자열이더라도 동일한 해시 값을 가질 수 있다. 이를 해시 충돌이라고 하는데, 좋은 해시 함수는 최대한 충돌이 적게 일어나야 한다. 위에서 정의한 해시 함수는 알파벳의 순서만 바꿔도 충돌이 일어나기 때문에 나쁜 해시 함수이다. 그러니까 조금 더 개선해보자.

어떻게 하면 순서가 달라졌을때 출력값도 달라지게 할 수 있을까? 머리를 굴리면 수열의 각 항마다 고유한 계수를 부여하면 된다는 아이디어를 생각해볼 수 있다. 가장 대표적인 방법은 항의 번호에 해당하는 만큼 특정한 숫자를 거듭제곱해서 곱해준 다음 더하는 것이 있다. 이를 수식으로 표현하면 아래와 같다.

 H=∑i=0l−1airimodM

보통 r과 M은 서로소인 숫자로 정하는 것이 일반적이다. 우리가 직접 정하라고 하면 힘들테니까 r의 값은 26보다 큰 소수인 31로 하고 M의 값은 1234567891(놀랍게도 소수이다!!)로 하자.

이제 여러분이 할 일은 위 식을 통해 주어진 문자열의 해시 값을 계산하는 것이다. 그리고 이 함수는 간단해 보여도 자주 쓰이니까 기억해뒀다가 잘 써먹도록 하자.

 

 입력

 

첫 줄에는 문자열의 길이 L이 들어온다. 둘째 줄에는 영문 소문자로만 이루어진 문자열이 들어온다.

입력으로 주어지는 문자열은 모두 알파벳 소문자로만 구성되어 있다.

 

 출력

 

문제에서 주어진 해시함수와 입력으로 주어진 문자열을 사용해 계산한 해시 값을 정수로 출력한다.

 

 Python 코드

 

def solution(arr):
    return sum(arr) / len(arr)

 

 

 C++ 코드

 

 

 

 출처

 

 

바이러스

 

 문제 설명

 

신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.

예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.

어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.

 

 입력

 

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.

 

 출력

 

1번 컴퓨터가 웜 바이러스에 걸렸을 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 첫째 줄에 출력한다.

 

 입출력 예제

 

 

 Python 코드

 

# 정점의 연결정보 입력받기
n= int(input())  				 # 정점 // 컴퓨터의 수
m = int(input()) 				 # 연결수 // 연결된 컴퓨터 쌍의 수
graph = [[] for _ in range(n+1)] # 연결된 컴퓨터 쌍의 수 만큼 반복 
for _ in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
 
visited_dfs = []
 
def dfs(graph, cur_node, visited):
    # 현재 노드를 방문처리
    visited.append(cur_node)
    graph[cur_node].sort()
    # 현재 노드와 인접한 노드를 확인
    for link_node in graph[cur_node]:
        # 방문하지 않은 노드라면 재귀호출
        if link_node not in visited:
            dfs(graph, link_node, visited)
 
dfs(graph, 1, visited_dfs)
print(len(visited_dfs)-1)

 

* DFS 참고 링크 1 : https://jiwon-coding.tistory.com/93

* DFS 참고 링크 2 : https://devmath.tistory.com/21

 

from collections import deque
n=int(input())
m=int(input())
computers=[[0]*(n+1) for _ in range(n+1)]
for _ in range(m):
    a,b=map(int,input().split())
    computers[a][b]=1
    computers[b][a]=1
visited=[0]*(n+1)
q=deque()
q.append(1)
visited[1]=1
cnt=0
while q:
    now=q.popleft()
    for i in range(1,n+1):
        if computers[now][i]==1 and visited[i]==0:  #연결되어있고 방문한적없으면
            visited[i]=1
            q.append(i)
            cnt+=1
print(cnt)

* BFS 참고 링크 : https://velog.io/@wjdtmdgml/%EB%B0%B1%EC%A4%80%EB%B0%94%EC%9D%B4%EB%9F%AC%EC%8A%A42606%EB%B2%88Python%ED%8C%8C%EC%9D%B4%EC%8D%ACBFS

 

 C++ 코드

 

#include <stdio.h>
#include <stdlib.h>
 
int map[101][101] = {0};
int visit[101] = {0};
int computer_num, ans = 0;
 
void dfs(int n){
    ans++;
    visit[n] = 1;
    for (int i=1; i<=computer_num; i++){
        if (map[n][i] && !visit[i])        
            dfs(i);
    }
}
 
int main(){
    int n;
    int x, y;
    scanf("%d %d", &computer_num, &n);
    for (int i=0; i<n; i++){
        scanf("%d %d", &x, &y);
        map[x][y] = map[y][x] = 1;
    }
 
    dfs(1);
    printf("%d\n", ans - 1);
 
 
}

* DFS 참고 링크 : https://code-kh-studio.tistory.com/30

#include <iostream>
#include <queue>
using namespace std;
 
int V, E;
const int MAX = 101;
int map[MAX][MAX] = { 0, };
bool visited[MAX] = { 0, };
int ans = 0;
queue<int> q;
 
void BFS(int v) {
    visited[v] = true;
    //cout << v << " ";
 
    q.push(v);
    while (!q.empty()) {
        v = q.front();
        q.pop();
        for (int i = 1; i <= V; i++) {
            if (visited[i] == 0 && map[v][i] == 1) {
                q.push(i);
                visited[i] = true;
                ans++;
                //cout << i << " ";
            }
        }
 
    }
}
 
int main() {
    cin >> V >> E;
    for (int i = 0; i < E; i++) {
        int a, b;
        cin >> a >> b;
        map[a][b] = 1;
        map[b][a] = 1;
    }
 
    BFS(1);
    
    cout << ans;
}

* BFS 참고 링크 : https://scarlettb.tistory.com/78

 출처

 

https://www.acmicpc.net/problem/2606

DFS와 BFS

 

 문제 설명

 

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

 

 입력

 

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

 

 출력

 

첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.

 

 입출력 예제

 

 Python 코드

 

n,m,v = map(int,input().split())
graph = [[] * n for _ in range(n+1)]
for _ in range(m):
    a,b = map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)
    
visited = [0] * (n+1)
def dfs(v):
    print(v,end=' ')
    global visited, graph
    visited[v] = 1
    for i in sorted(graph[v]):
        if visited[i]!=1:
            dfs(i)
dfs(v)
print()
from collections import deque
visited = [0] * (n+1)
def bfs(start):
    global visited, graph
    queue = deque([start])
    visited[start] = 1
    
    while queue:
        v = queue.popleft()
        print(v,end=' ')
        for i in sorted(graph[v]):
            if visited[i]!=1:
                queue.append(i)
                visited[i] = 1
bfs(v)

* 참고 링크 : https://jiwon-coding.tistory.com/91

 

 C++ 코드

 

#include <iostream>
#include <queue>
using namespace std;
#define MAX 1001
 
int N, M, V; //정점개수, 간선개수, 시작정점
int map[MAX][MAX]; //인접 행렬 그래프
bool visited[MAX]; //정점 방문 여부
queue<int> q;
 
void reset() {
    for (int i = 1; i <= N; i++) {
        visited[i] = 0;
    }
}
 
void DFS(int v) {
    visited[v] = true;
    cout << v << " ";
    
    for (int i = 1; i <= N; i++) {
        if (map[v][i] == 1 && visited[i] == 0) { //현재 정점과 연결되어있고 방문되지 않았으면
            DFS(i);
        }
    }
}
 
void BFS(int v) {
    q.push(v);
    visited[v] = true;
    cout << v << " ";
 
    while (!q.empty()) {
        v = q.front();
        q.pop();
        
        for (int w = 1; w <= N; w++) {
            if (map[v][w] == 1 && visited[w] == 0) { //현재 정점과 연결되어있고 방문되지 않았으면
                q.push(w);
                visited[w] = true;
                cout << w << " ";
            }
        }
    }
}
 
int main() {
    cin >> N >> M >> V;
 
    for (int i = 0; i < M; i++) {
        int a, b;
        cin >> a >> b;
        map[a][b] = 1;
        map[b][a] = 1;
    }
 
    reset();
    DFS(V);
    
    cout << '\n';
    
    reset();
    BFS(V);
 
    return 0;
}

* 참고 링크 : https://scarlettb.tistory.com/76

 출처

 

https://www.acmicpc.net/problem/1260

진법 변환

 

 문제 설명

 

B진법 수 N이 주어진다. 이 수를 10진법으로 바꿔 출력하는 프로그램을 작성하시오.

10진법을 넘어가는 진법은 숫자로 표시할 수 없는 자리가 있다. 이런 경우에는 다음과 같이 알파벳 대문자를 사용한다.

A: 10, B: 11, ..., F: 15, ..., Y: 34, Z: 35

 

 입력

 

첫째 줄에 N과 B가 주어진다. (2 ≤ B ≤ 36)

B진법 수 N을 10진법으로 바꾸면, 항상 10억보다 작거나 같다.

 

 출력

 

첫째 줄에 B진법 수 N을 10진법으로 출력한다.

 

 Python 코드

 

a, b = input().rstrip().split()
print(int(a, int(b)))

 

* 참고 링크 : https://my-coding-notes.tistory.com/344

https://codechacha.com/ko/python-string-strip/

 

Python - String strip(), rstrip(), lstrip() 사용 방법 및 예제

Python에서 strip() 함수를 이용하면 문자열의 쓸모 없는 부분을 자를 수 있습니다. Python은 lstrip(), rstrip(), strip()을 제공합니다. Java 등의 다른 언어들도 strip()을 제공하며, 기능은 모두 비슷합니다.

codechacha.com

 

 C++ 코드

 

#include <iostream>
#include <string>
using namespace std;

int main() {
	string s;
	int b, sum = 0;
	cin >> s >> b;
	for (int i=0; i<s.size(); i++) {	// 문자열 크기만큼 반복
		if (s[i] >= '0' && s[i] <= '9') {		// 수가 문자가 아닌 경우
			sum = sum*b + (s[i] - 48);		// 문자 0 의 아스키코드 : 48
		}
		else 
			sum = sum*b + (s[i] - 65 + 10);		// 문자 A 의 아스키코드 : 65
	}
	cout << sum;
		return 0;
}

 

* 참고 링크 : https://etyoungsu.tistory.com/54

 

 출처

 

https://www.acmicpc.net/problem/2745

팩토리얼 진법

 

 문제 설명

 

상근이는 보통 사람들이 사는 것과는 조금 다른 삶을 사는 사람이다. 상근이는 이런 사람들의 시선이 부담스럽기 때문에, 자신만의 숫자를 개발하기로 했다. 바로 그 이름은 팩토리얼 진법이다. 팩토리얼 진법은 각 자리에 올 수 있는 숫자는 0부터 9까지로 10진법과 거의 비슷하다. 하지만, 읽는 법은 조금 다르다. 팩토리얼 진법에서는 i번 자리의 값을 ai×i!로 계산한다. 즉, 팩토리얼 진법에서 719는 10진법에서 53과 같다. 그 이유는 7×3! + 1×2! + 9×1! = 53이기 때문이다.

팩토리얼 진법으로 작성한 숫자가 주어졌을 때, 10진법으로 읽은 값을 구하는 프로그램을 작성하시오. 

 

 입력

 

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 최대 5자리인 팩토리얼 진법 숫자가 주어진다. 입력의 마지막 줄에는 0이 하나 주어진다.

 

 출력

 

각 테스트 케이스에 대해서, 입력으로 주어진 팩토리얼 진법 숫자를 10진법으로 읽은 값을 출력한다.

 

 Python 코드

 

from sys import stdin                      # readline을 사용하기 위해 import
from math import factorial                 # factorial을 사용하기 위해 import

while True:                                # 0을 입력할 때까지 반복
    number = stdin.readline().rstrip()     # 팩토리얼 진법 숫자 입력  

    number_len = len(number)               # 입력한 팩토리얼 진법 숫자의 길이를 저장하는 변수 선언

    decimal_number = 0                     # 팩토리얼 진법 숫자를 10진법으로 읽은 값을 저장할 변수 선언

    if number == '0':                      # 입력한 팩토리얼 진법 숫자가 0이라면
        break                              # 반복문 탈출

    for i in range(number_len):            # 팩토리얼 진법 숫자의 길이만큼 반복
        decimal_number += int(number[i]) * factorial(number_len -i)
                                           # 팩토리얼 진법 숫자에서 i번 자리의 값을 10진법으로 계산해
                                           # decimal_number에 더한다.

    print(decimal_number)                  # 팩토리얼 진법 숫자를 10진법 숫자로 읽은 값을 출력

* 참고 링크 : https://brightnightsky77.tistory.com/313

 

 C++ 코드

 

#include <bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int getFac(int num){
    int tmp = 1;
    for(int i = 1; i <= num; i++)
        tmp *= i;
    return tmp;
}

int getFacNum(int num) {
    int tmp = num, sum = 0, cnt = 1;
    while(tmp){
        sum += tmp % 10 * getFac(cnt++);
        tmp /= 10;
    }
    return sum;
}

int main(){
    fastio;
    while(1){
        int n, ans = 0;
        cin >> n;
        if(!n) break;
        cout << getFacNum(n) << '\n';
    }
}

* 참고 링크 : https://codecollector.tistory.com/1336

 출처

 

https://www.acmicpc.net/problem/5692

숫자 카드 2

 

 문제 설명

 

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.

 

 입력

 

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

 출력

 

첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.

 예제 입출력

 

 Python 코드

 

from sys import stdin
from collections import Counter

# 1. n 입력
n = int(stdin.readline())

# 2. n개의 정수
arr = list(map(int, stdin.readline().split()))

# 3. m 입력
m = int(stdin.readline())

# 4. m개의 정수
find = list(map(int, stdin.readline().split())) 

# 5. counter 함수 활용
count = Counter(arr)

# print(count)
print(' '.join(str(count[x])   if x in count else '0' for x in find ))

* 참고 링크 : https://0equal2.tistory.com/62

 

 C++ 코드

 

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

int n,m; 
vector<int> arr; 
vector<int> target; 

int main() { 
	ios_base :: sync_with_stdio(false); 
	cin.tie(NULL); cout.tie(NULL); 
	cin >> n; 
	
	int count[n]={0,}; 
	for(auto i = 0;i<n;i++) { 
		int x; 
		cin >> x; 
		arr.push_back(x); 
	} 
	
	sort(arr.begin(),arr.end()); 
	
	cin >> m; 
	for(auto i =0; i<m;i++) { 
		int x; 
		cin >> x; 
		
		cout << upper_bound(arr.begin(),arr.end(),x) - lower_bound(arr.begin(),arr.end(),x)<< " "; 
	} 
}

* 참고 링크 : https://tooo1.tistory.com/126

 출처

 

https://www.acmicpc.net/problem/10816

2557. hello World

 

Python

print("Hello World!")

 

C++

방법 1) [iostream]

#include <iostream>
 
int main() {
    std::cout << "Hello World!";
    return 0;
}

방법 2) [stdio.h]

#include <stdio.h>
 
int main() {
    printf("Hello World!");
    return 0;
}

방법 3) [cstdio]

include <cstdio>
 
int main() {
    printf("Hello World!");
    return 0;
}

 

* 참고: https://st-lab.tistory.com/200

+ Recent posts