728x90
 

10988번: 팰린드롬인지 확인하기

첫째 줄에 단어가 주어진다. 단어의 길이는 1보다 크거나 같고, 100보다 작거나 같으며, 알파벳 소문자로만 이루어져 있다.

www.acmicpc.net

파이썬은 문자열이나 리스트 다루기가 굉장히 편하다는 것을 다시 한 번 느낀다.

s[-1] 이런 음수 인덱스가 된다는게  참 편리하다.

s = input()
flag = 1
for i in range(len(s) //2):
    if s[i] != s[-(i + 1)]:
        flag = 0
        break
print(flag)
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 4344번 평균은 넘겠지  (0) 2020.01.20
[백준] 10172번 개  (0) 2020.01.20
[백준] 17072번 아스키 아트  (0) 2020.01.19
[백준] 17070번 파이프 옮기기 1  (0) 2020.01.18
[백준] 2442번 별 찍기 - 5  (0) 2020.01.18
728x90

2019 연세대학교 컴퓨터과학과 프로그래밍 경진대회 A번 문제

 

17072번: 아스키 아트

위와 같이, 아스키 문자로 그린 그림을 ‘아스키 아트’ 라고 한다. 우리가 알고 있는 일반적인 그림 파일(.jpg, .png 등)들은 기본적으로 해상도에 맞게 픽셀 단위로 분할된 2차원 그리드에 대해 각 픽셀의 정보를 담는 방식으로 저장된다. 이 정보에는 여러 가지가 있으나, 그중 ‘R’, ‘G’, ‘B’ 값은 ‘Red’, ‘Green’, ‘Blue’의 3색이 각각 어느 정도 섞여 있는지를 나타내 주는 지표이며, 각 값은 0 이상 255 이하의 범위에 있

www.acmicpc.net

 

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

int main() {
	int n, m;
	cin >> n >> m;
	vector<vector<int>> li(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			int r, g, b;
			cin >> r >> g >> b;
			li[i][j] = 2126 * r + 7152 * g + 722 * b;
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (li[i][j] < 510000)
				cout << (char)35;
			else if (li[i][j] < 1020000)
				cout << (char)111;
			else if (li[i][j] < 1530000)
				cout << (char)43;
			else if (li[i][j] < 2040000)
				cout << (char)45;
			else cout << (char)46;
		}
		cout << endl;
	}
	return 0;
}

 

728x90
728x90

삼성 A형 기출 문제인 17070번

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의 번호이고, 행과 열의 번호는 1부터 시작한다. 각각의 칸은 빈 칸이거나 벽이다. 오늘은 집 수리를 위해서 파이프 하나를 옮기려고 한다. 파이프는 아래와 같은 형태이고, 2개의 연속된 칸을 차지하는 크기이다. 파이프는 회전시킬 수 있으며, 아래와 같이

www.acmicpc.net

이렇게 BFS로 풀어서 제출했는데 시간초과가 났다.

n = int(input())
from sys import stdin
li = []
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))
import collections
q = collections.deque()
q.append(((0, 0), (0, 1)))
count = 0
while q:
    cur = q.popleft()
    if cur[1] == (n - 1, n - 1):
        count += 1
    if cur[0][0] == cur[1][0]:
        if cur[1][1] + 1 < n and li[cur[1][0]][cur[1][1] + 1] == 0:
            q.append((cur[1], (cur[1][0], cur[1][1] + 1)))
        if cur[1][1] + 1 < n and cur[1][0] + 1 < n and li[cur[1][0]][cur[1][1] + 1] == 0 and li[cur[1][0] + 1][cur[1][1]] == 0 and  li[cur[1][0] + 1][cur[1][1] + 1] == 0:
            q.append((cur[1], (cur[1][0] + 1, cur[1][1] + 1)))
    elif cur[0][1] == cur[1][1]:
        if cur[1][0] + 1 < n and li[cur[1][0] + 1][cur[1][1]] == 0:
            q.append((cur[1], (cur[1][0] + 1, cur[1][1])))
        if cur[1][1] + 1 < n and cur[1][0] + 1 < n and li[cur[1][0]][cur[1][1] + 1] == 0 and li[cur[1][0] + 1][cur[1][1]] == 0 and  li[cur[1][0] + 1][cur[1][1] + 1] == 0:
            q.append((cur[1], (cur[1][0] + 1, cur[1][1] + 1)))
    else:
        if cur[1][1] + 1 < n and li[cur[1][0]][cur[1][1] + 1] == 0:
            q.append((cur[1], (cur[1][0], cur[1][1] + 1)))
        if cur[1][0] + 1 < n and li[cur[1][0] + 1][cur[1][1]] == 0:
            q.append((cur[1], (cur[1][0] + 1, cur[1][1])))
        if cur[1][1] + 1 < n and cur[1][0] + 1 < n and li[cur[1][0]][cur[1][1] + 1] == 0 and li[cur[1][0] + 1][cur[1][1]] == 0 and  li[cur[1][0] + 1][cur[1][1] + 1] == 0:
            q.append((cur[1], (cur[1][0] + 1, cur[1][1] + 1)))
print(count)

찾아보니까 이 방법으로 풀려면 파이썬이 아닌 다른 언어로 풀어야 한다고 한다.

파이썬으로 풀어서 맞으신 분들은 다 동적계획법으로 푸신 분들만 맞았다고 한다.

역시 알고리즘 풀 때 쓰는 언어를 C++로 바꿔야 하는 걸까

가장 오래 배운 언어가 C++(2018년 3월에 처음 접함)이고 그 다음이 Java(2018년 9월에 처음 접함), 그리고 파이썬(2019년 9월에 처음 접함)이 가장 최근에 배운건데

요즘에 안 써서 그런지 C++은 어색해지고 오히려 배운지 6개월도 안 된 언어인 파이썬이 가장 편해졌다.

파이썬이 문자열 다루기도 좋고 다른 부분에서도 정말 편한데 고민이다.

 

다음 날 2020.01.19

위의 코드를 그대로 C++로 바꿔서 성공

#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<vector> li(n, vector(n));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> li[i][j];
		}
	}
	queue<pair<pair<int, int>, pair<int, int>>> q;
	q.push(make_pair(make_pair(0, 0), make_pair(0, 1)));
	int count = 0;
	while (!q.empty()) {
		int row1 = q.front().first.first;
		int col1 = q.front().first.second;
		int row2 = q.front().second.first;
		int col2 = q.front().second.second;
		q.pop();
		if (row2 == n - 1 && col2 == n - 1) {
			count++;
			continue;
		}
		if (row1 == row2) {
			if (col2 + 1 < n && li[row2][col2 + 1] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2, col2 + 1)));
			if (col2 + 1 < n && row2 + 1 < n && li[row2][col2 + 1] == 0 && li[row2 + 1][col2] == 0 && li[row2 + 1][col2 + 1] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2 + 1, col2 + 1)));
		}
		else if (col1 == col2) {
			if (row2 + 1 < n && li[row2 + 1][col2] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2 + 1, col2)));
			if (col2 + 1 < n && row2 + 1 < n && li[row2][col2 + 1] == 0 && li[row2 + 1][col2] == 0 && li[row2 + 1][col2 + 1] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2 + 1, col2 + 1)));
		}
		else {
			if (col2 + 1 < n && li[row2][col2 + 1] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2, col2 + 1)));
			if (row2 + 1 < n && li[row2 + 1][col2] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2 + 1, col2)));
			if (col2 + 1 < n && row2 + 1 < n && li[row2][col2 + 1] == 0 && li[row2 + 1][col2] == 0 && li[row2 + 1][col2 + 1] == 0)
				q.push(make_pair(make_pair(row2, col2), make_pair(row2 + 1, col2 + 1)));
		}
	}
	cout << count << endl;
	return 0;
}

역시 C/C++이 속도 면에서는 확실히 우수하다.

<tuple>이라는 라이브러리의 pair과 make_pair() 함수 꼭 기억해야겠다.

이걸 이용하니 클래스나 구조체를 따로 만들지 않아도 돼서 편하다.

728x90
728x90

별찍기 문제집의 5번째 문제

 

2442번: 별 찍기 - 5

첫째 줄에는 별 1개, 둘째 줄에는 별 3개, ..., N번째 줄에는 별 2×N-1개를 찍는 문제 별은 가운데를 기준으로 대칭이어야 한다.

www.acmicpc.net

n = int(input())
for i in range(1, n + 1):
    print(" " * (n - i), end="")
    print("*" * (2 * i - 1))
728x90
728x90

별 찍기 문제집의 3번째 문제이다

 

2440번: 별 찍기 - 3

첫째 줄에는 별 N개, 둘째 줄에는 별 N-1개, ..., N번째 줄에는 별 1개를 찍는 문제

www.acmicpc.net

n = int(input())
for i in range(n, 0, -1):
    print("*" * i)
728x90
728x90

2019 인하대학교 프로그래밍 경진대회(IUPC) D번 문제

 

17266번: 어두운 굴다리

인하대학교 후문 뒤쪽에는 어두운 굴다리가 있다. 겁쟁이 상빈이는 길이 조금이라도 어둡다면 가지 않는다. 따라서 굴다리로 가면 최단거리로 집까지 갈수 있지만, 굴다리는 어둡기 때문에 빙빙 돌아서 집으로 간다. 안타깝게 여긴 인식이는 굴다리 모든 길 0~N을 밝히게 가로등을 설치해 달라고 인천광역시에 민원을 넣었다. 인천광역시에서 가로등을 설치할 개수 M과 각 가로등의 위치 x들의 결정이 끝냈다. 그리고 각 가로등은 높이만큼 주위를 비출 수 있다. 하지만 갑

www.acmicpc.net

from sys import stdin
n = int(input())
m = int(input())
location = list(map(int, stdin.readline().split()))
gap = []
gap.append((location[0] - 0) * 2)
for i in range(1, m):
    gap.append(location[i] - location[i - 1])
gap.append((n - location[-1]) * 2)
a, b = divmod(max(gap), 2)
if b == 0:
    print(a)
else:
    print(a + 1)
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2442번 별 찍기 - 5  (0) 2020.01.18
[백준] 2440번 별 찍기 - 3  (0) 2020.01.18
[백준] 17264번 I AM IRONMAN  (0) 2020.01.18
[백준] 17269번 이름궁합 테스트  (0) 2020.01.18
[백준] 1932번 정수 삼각형  (0) 2020.01.18
728x90

2019 인하대학교 프로그래밍 경진대회(IUPC) B번 문제

 

17264번: I AM IRONMAN

다들 문제 제목을 보고 요즘 가장 핫한 영화를 생각했겠지만 이 이야기는 LUL(League Us Legends) 게임에서 아이언(Iron) 티어에 있는 형동이의 슬픈 이야기이다. LUL에서 티어는 게임 실력을 판가름할 수 있는 지표이다. 그중 아이언 티어는 가장 낮은 단계에 위치해 있다. 친구인 강엽이와 건홍이에게 “Ironman”이라며 게임을 못한다고 놀림당하던 형동이는 꼭 아이언 티어에서 벗어나겠다고 결심했다. 하지만 형동이는 자신의 실력으로 절대 아

www.acmicpc.net

from sys import stdin
n, p = list(map(int, stdin.readline().split()))
w, l, g = list(map(int, stdin.readline().split()))
win = []
lose = []
for i in range(p):
    name, what = stdin.readline().split()
    if what == 'W':
        win.append(name)
    else:
        lose.append(name)
li = []
sum = 0
flag = False
for i in range(n):
    n = input()
    if n in win:
        sum += w
    else:
        if sum - l >= 0:
            sum -= l
        else:
            sum = 0
    if sum >= g:
        print("I AM NOT IRONMAN!!")
        flag = True
        break
if not flag:
    print("I AM IRONMAN!!")

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2440번 별 찍기 - 3  (0) 2020.01.18
[백준] 17266번 어두운 굴다리  (0) 2020.01.18
[백준] 17269번 이름궁합 테스트  (0) 2020.01.18
[백준] 1932번 정수 삼각형  (0) 2020.01.18
[백준] 14890번 경사로  (0) 2020.01.16
728x90

2019 인하대학교 프로그래밍 경진대회(IUPC) G번 문제

 

17269번: 이름궁합 테스트

시윤이는 좋아하는 이성이 생기면 가장 먼저 이름궁합부터 본다. 이름궁합을 보는 방법은 간단하다. 먼저 이름을 알파벳 대문자로 적는다. 각 알파벳 대문자에는 다음과 같이 알파벳을 적는데 필요한 획수가 주어진다. 예를 들어, 두 사람의 이름인 LEESIYUN, MIYAWAKISAKURA 를 같이 표현했을 때 다음과 같이 먼저 주어진 이름부터 한 글자씩 적는다. 두 사람의 이름을 알파벳 대문자로 표현한 뒤, 한 글자씩 번갈아가며 적는다. 예시 :  L M E

www.acmicpc.net

from sys import stdin
n, m = list(map(int, stdin.readline().split()))
n1, n2 = stdin.readline().split()
n1_index = 0
n2_index = 0
s = ""
alphabet = {'A':3, 'B':2, 'C':1, 'D':2, 'E':4, 'F':3, 'G':1, 'H':3, 'I':1, 'J':1, 'K':3, 'L':1, 'M':3, 'N':2, 'O':1, 'P':2, 'Q':2, 'R':2, 'S':1, 'T':2, 'U':1, 'V':1, 'W':1, 'X':2, 'Y':2, 'Z':1}
while not (n1_index == n and n2_index == m):
    if n1_index < len(n1):
        s += n1[n1_index]
        n1_index += 1
    if n2_index < len(n2):
        s += n2[n2_index]
        n2_index += 1
count = [0] * (n + m)
for i in range(n + m):
    count[i] = alphabet[s[i]]
for i in range(n + m - 1, 1, -1):
    for j in range(i):
        count[j] = (count[j] + count[j + 1]) % 10
print("{}%".format(count[0] * 10 + count[1]))
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 17266번 어두운 굴다리  (0) 2020.01.18
[백준] 17264번 I AM IRONMAN  (0) 2020.01.18
[백준] 1932번 정수 삼각형  (0) 2020.01.18
[백준] 14890번 경사로  (0) 2020.01.16
[백준] 14503 로봇 청소기  (0) 2020.01.15
728x90

단계별로 풀어보기 동적계획법1의 6단계 문제

 

1932번: 정수 삼각형

문제 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 위 그림은 크기가 5인 정수 삼각형의 한 모습이다. 맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다. 삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는

www.acmicpc.net

이렇게 bfs로 풀어서 제출했는데

n = int(input())
from sys import stdin
li = []
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))
sum = []
import collections
q = collections.deque()
q.append((0, 0, li[0][0]))
while q:
    cur = q.popleft()
    if cur[0] == n - 1:
        sum.append(cur[2])
    else:
        q.append((cur[0] + 1, cur[1], cur[2] + li[cur[0] + 1][cur[1]]))
        q.append((cur[0] + 1, cur[1] + 1, cur[2] + li[cur[0] + 1][cur[1] + 1]))
print(max(sum))

메모리 초과로 실패

 

그래서 삼각형 아랫쪽부터 위로 올라오는 방식으로 동적계획법을 사용한 코드로 바꾸었다.

n = int(input())
from sys import stdin
li = []
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))
    li[i].extend([0] * (n - 1 - i))
for i in range(n - 2, -1, -1):
    for j in range(i + 1):
        li[i][j] = max(li[i][j] + li[i + 1][j], li[i][j] + li[i + 1][j + 1])
print(li[0][0])

성공

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 17264번 I AM IRONMAN  (0) 2020.01.18
[백준] 17269번 이름궁합 테스트  (0) 2020.01.18
[백준] 14890번 경사로  (0) 2020.01.16
[백준] 14503 로봇 청소기  (0) 2020.01.15
[백준] 1149번 RGB 거리  (0) 2020.01.12
728x90

삼성 SW 역량 테스트 기출 문제인 14890번 문제

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

 

from sys import stdin
n, l = list(map(int, stdin.readline().split()))
li = []
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))
count = 0
for i in range(n):
    previous = -1
    seq = []
    maximum = -1
    for j in range(n):
        if j == 0:
            maximum = li[i][j]
            seq.append([li[i][j], 1])
        else:
            if li[i][j] > maximum:
                maximum = li[i][j]
            if previous == li[i][j]:
                seq[-1][1] = seq[-1][1] + 1
            else:
                seq.append([li[i][j], 1])
        previous = li[i][j]
    if len(seq) == 1:
        count += 1
    elif n / l < len(seq):
        pass
    else:
        for k in range(len(seq)):
            if k > 0 and abs(seq[k - 1][0] - seq[k][0]) != 1:
                break
            elif seq[k][0] != maximum and seq[k][1] < l:
                break
            elif 0 < k < len(seq) - 1:
                if seq[k - 1][0] > seq[k][0] and seq[k + 1][0] > seq[k][0] and seq[k][1] < l * 2:
                    break
            else:
                if k == len(seq) - 1:
                    count += 1
for i in range(n):
    previous = -1
    seq = []
    maximum = -1
    for j in range(n):
        if j == 0:
            maximum = li[j][i]
            seq.append([li[j][i], 1])
        else:
            if li[j][i] > maximum:
                maximum = li[j][i]
            if previous == li[j][i]:
                seq[-1][1] = seq[-1][1] + 1
            else:
                seq.append([li[j][i], 1])
        previous = li[j][i]
    if len(seq) == 1:
        count += 1
    elif n / l < len(seq):
        pass
    else:
        for k in range(len(seq)):
            if k > 0 and abs(seq[k - 1][0] - seq[k][0]) > 1:
                break
            elif seq[k][0] != maximum and seq[k][1] < l:
                break
            elif 0 < k < len(seq) - 1:
                if seq[k - 1][0] > seq[k][0] and seq[k + 1][0] > seq[k][0] and seq[k][1] < l * 2:
                    break
            else:
                if k == len(seq) - 1:
                    count += 1
print(count)

seq의 원소는 [높이, 연속된 개수]로 되어있다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 17269번 이름궁합 테스트  (0) 2020.01.18
[백준] 1932번 정수 삼각형  (0) 2020.01.18
[백준] 14503 로봇 청소기  (0) 2020.01.15
[백준] 1149번 RGB 거리  (0) 2020.01.12
[백준] 9461번 파도반수열  (0) 2020.01.12

+ Recent posts