반응형

하라는 대로만 하면 되는 문제다. 시간이 빡빡해보였는데 한번에 통과해서 기분 좋다.

이 문제에서는 주의해야할 점은..... 죽은 나무를 언제 처리할 것인지 생각하는게 관건이다.

clear와 extend 함수 스킬을 알고 있어서 다행이었다.

# N은 격자 사이즈, M은 바이러스 개수, K는 사이클 횟수
N,M,K = map(int,input().split())

# 초기 배양액
init_eat = [[5]*N for _ in range(N)]

# 사이클 1회 마치고 추가될 양분
add_eat = []
for col in range(N):
    add_eat.append(list(map(int,input().split())))

# 바이러스 정보들
virus = [[[] for _ in range(N)] for _ in range(N)]
for col in range(M):
    y,x,age = map(int,input().split())
    virus[y-1][x-1].append(age)

# 방향 키
step = [(1,0),(0,1),(-1,0),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1)]

#### 입력 이상 X ####

# 1번/2번 행동 시작
def eating():
    for col in range(N):
        for row in range(N):
            if virus[col][row]: # 바이러스가 있는 곳이라면
                virus[col][row].sort() # 나이가 어린 바이러스부터 먹어야하므로,
                temp = []
                dead = 0
                for age in virus[col][row]:
                    if age <= init_eat[col][row]: # 양분이 나이보다 크거나 같을 경우
                        init_eat[col][row] -= age
                        age+=1
                        temp.append(age)

                    else:
                        dead += age//2 # 현재 나이의 절반만큼의 양분

                init_eat[col][row] += dead
                virus[col][row].clear() # 한번 싹 치워주고
                virus[col][row].extend(temp)


# 3번 행동 시작
def grow():
    for col in range(N):
        for row in range(N):
            if virus[col][row]: # 바이러스가 있다면
                for age in virus[col][row]:
                    if age%5==0:
                        for idx in step:
                            ny = col+idx[0]
                            nx = row+idx[1]
                            if 0<=ny<N and 0<=nx<N:
                                virus[ny][nx].append(1) # 나이가 1인 나무 추가

for _ in range(K):
    eating()
    grow()
    for col in range(N):
        for row in range(N):
            init_eat[col][row] += add_eat[col][row]

tot = 0
for col in range(N):
    for row in range(N):
        if virus[col][row]:
            tot += len(virus[col][row])

print(tot)
반응형
반응형

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

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸

www.acmicpc.net

백트랙킹을 사용하는 문제입니다.

import sys
sys.setrecursionlimit(10**8)
sys.stdin = open('111.txt')

N,M = map(int,input().split()) # N은 격자 사이즈, M은 치킨집 개수
graph = []
house = []
chicken = []


for col in range(N):
    graph.append(list(map(int,input().split())))
    for row in range(N):
        if graph[col][row] == 1:
            house.append((col,row))
            
        elif graph[col][row] == 2:
            chicken.append((col,row))

기본적으로 먼저 짜둬야 하는 코드들입니다.

그래프 정보를 받을 때, 집과 치킨집의 좌표를 따로 받아줍니다.

 

이제 백트랙킹을 이용해서 각 집마다 치킨집과의 거리를 다 구해볼게요.

2차원에서 각 좌표들끼리의 조합을 구하는 방법은 거의 공식처럼 쓰입니다.

혹시, 이 문제를 풀기 전에 백준에서 N과M 시리즈를 푸셨다면 1차원에서 조합을 짜는 법은

손에 익으셨을텐데요. 2차원에선 막막할겁니다.

 

안그렇다구요? 재능러시군요.

 

저는 일단 이 문제를 처음 봤을 때, combinations을 쓰면 풀 수는 있지만 재귀를 사용해서 풀고자 했습니다. 근데 아이디어가 안 떠올라서 모 블로그를 참고해서 구현하는 방법을 참고했어요. 알고보니 공식처럼 쓰이더라구요.

 

2차원에서 좌표를 조합하는 방법부터 먼저 짚고 가겠습니다. 금방합니다!

arr = []
def back(num,cnt):
    if num>len(chicken):
        return
    
    if cnt==M:
        for idx in arr:
            cx,cy = chicken[idx]
            print((cx,cy),end=" ")
        return

    arr.append(num)
    back(num+1,cnt+1)
    arr.pop()
    back(num+1,cnt)

(back(0,0))

자, 이게 공식처럼 쓰이는 2차원 백트랙킹 조합 코드입니다.

 

아래 테케를 기준으로 위 백트랙킹 코드로 치킨집 좌표들을 뽑아보면요.

5 2
0 2 0 1 0
1 0 1 0 0
0 0 0 0 0
2 0 0 1 1
2 2 0 1 2

구분이 잘 안가있지만

(0,1) , (3,0)

(0,1) , (4,0)

(0,1) , (4,1)

.

.

.

이런 식으로 좌표가 스윽 나옵니다.

여기서 num > len(chicken)의 역할은 치킨 리스트에 담은 좌표들의 개수보다 넘어가면 인덱스에러가 뜨기때문에, 그걸 잡아주는 역할을 합니다. cnt는 최대 몇개의 좌표를 뽑을지 보는 것이라 cnt==M이 되면 이제 좌표 쌍을 뽑도록 합니다.

 

위 코드는 그냥 공식처럼 받아들이시면 됩니다.

 

그렇게 치킨 좌표들 다 뽑았으면 이제 집이랑 같이 이중 포문 돌려서 각각의 거리들을의 모든 합을 다 구해주면 됩니다.

그걸 min함수를 이용해서 계속 갱신해주면 되겠습니다.

 

아래는 해답코드이며 복붙해가실 때는 sys.stdin = open 이부분 주석처리해주세요~

import sys
sys.setrecursionlimit(10**8)
sys.stdin = open('111.txt')

N,M = map(int,input().split()) # N은 격자 사이즈, M은 치킨집 개수
graph = []
house = []
chicken = []


for col in range(N):
    graph.append(list(map(int,input().split())))
    for row in range(N):
        if graph[col][row] == 1:
            house.append((col,row))
            
        elif graph[col][row] == 2:
            chicken.append((col,row))


arr = []
real_check = int(1e9)
def back(num,cnt):
    global real_check
    if num>len(chicken):
        return
    
    if cnt==M:
        result_tot = 0
        for hx,hy in house:
            min_check = int(1e9)
            for idx in arr:
                cx,cy = chicken[idx]
                min_check = min(min_check,abs(hx-cx)+abs(hy-cy))
                
            result_tot+=min_check
            
        real_check = min(result_tot,real_check)
        return

    arr.append(num)
    back(num+1,cnt+1)
    arr.pop()
    back(num+1,cnt)
    return real_check

print(back(0,0))
반응형
반응형

PROJECTION : 컬럼명을 지정해서 데이터를 가져오는 쿼리문

SELECT NAME FROM TABLE
	ORDER BY SAL LIMIT 1

위 코드의 경우는 테이블에서 NAME컬럼만 출력한다. 근데 출력할 때는 SAL(연봉)을 기준으로 해서 가장 제일 위에 뜨는거 하나만 출력하는 형태이다.

 

SELECTION : 전체 혹은 원하는 컬럼만을 가져오는 것

* 표시나 WHERE과 같다

 

SELECT관련된 문제를 하나 풀이 해보았다.

https://school.programmers.co.kr/learn/courses/30/lessons/131535

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해당 문제는 주어진 테이블에서 2021년에 가입한 회원 중, 나이가 20~29 사이인 회원의 수를 카운팅하는 것이다.

SELECT COUNT(AGE) AS USERS FROM USER_INFO
    WHERE year(JOINED) = '2021' AND AGE>=20 AND AGE<=29

조건은 2가지를 줬다. 2021년에 가입했으며 20대인 회원이다. 따라서 WHERE절을 사용했다.

SQL에서 쿼리의 실행순서는

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT 이다.

즉, 이 순서대로 해석하자면  USER_INFO라는 테이블에서(FROM)  가입연도가 2021년이고, 나이는 20~29살 사이 (WHERE) 인 회원들 출력하는데 USERS라는 별칭으로 출력해라 (SELECT) 라는 것이다.

 

COUNT(칼럼명)은  해당 칼럼의 데이터 수를 세라는 것이고, 뒤에 AS는 기존 칼럼명에서 다른 칼럼명으로 바꾼다는 의미다. 따라서 AGE -> USERS로 바꾼 것이다.

 

문제를 하나 더 풀자면

https://school.programmers.co.kr/learn/courses/30/lessons/144853

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

SELECT BOOK_ID, DATE_FORMAT(PUBLISHED_DATE,'%Y-%m-%d') AS PUBLISHED_DATE FROM BOOK
    WHERE year(PUBLISHED_DATE) = '2021' and CATEGORY = '인문'
    ORDER BY PUBLISHED_DATE

문제는 BOOK이라는 테이블에서  조건 1) 2021년에 출판된  조건 2) 인문 카테고리에 속하는 도서 리스트를 찾아서

도서ID와 출판일로 출력하라는 SQL문을 작성해달라고 한다. 결과는 출판일 기준으로 오름차순 정렬이다.

 

살짝 까다로울 수도 있는데 아직 어려운 수준은 아니다.

조건들은 WHERE에 넣어주면 되는데 DATE_FORMAT이란게 있다. 기본적으로  날짜함수는

Y,M,D뿐만 아니라 뒤에 시-분-초까지도 다 나온다. 근데 문제에서 요구하는건 시,분,초는 생략하는 것이므로

DATE_FORMAT이라는 함수를 사용했다. 이를 사용하는 방법은 위와 같다.

 

별칭은 잊지말자.

https://school.programmers.co.kr/learn/courses/30/lessons/133024

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

SELECT FLAVOR FROM FIRST_HALF
    ORDER BY TOTAL_ORDER DESC , SHIPMENT_ID ASC

SELECT문의 마지막 문제로 가져왔다.

이 문제는 TOTAL_ORDER를 내림차순으로 하되, 같은 값을 가질 땐 SHIPMENT_ID를 기준으로 오름차순시키라는 문제다. 다른 언어와 달리 따로 조건문을 쓸 필요없이 위 코드처럼 짜놓으면 된다.

반응형
반응형

SCSA 교육 입과 전, Python 기초 문법을 예습해가는 시간을 갖고자 합니다.

 

먼저 산술연산자 4개부터 봅시다. 당연한 사칙연산들인데요.  C/C++에선 + , - , / , %이 있습니다.

파이썬에서는 특이한게 +,-,/,//,%,divmod(a,b) 로 크게 6가지가 있어요.

 

+ 는 더하기 ,  - 빼기 , / 는 소수점자리까지 출력하는 나누기  , // 는 몫만 출력 (C/C++에선 주석처리였죠?) , % 는 나머지 출력 ,  divmod(a,b)는  a//b , a%b를 동시에 출력하는 문법입니다.

 

 

다음은 문자열입니다. C/C++에선  문자는 작은따옴표로 , 문자열은 큰따옴표로 구분했는데 파이썬은 상관없습니다.

작은따옴표로 하든 큰따옴표로 하든  알아서 다 인식이 됩니다.

a = 'abc'

b = 'def'   이렇게 있을 때, 문자열 연산은

print(a+b)의 결과는 abcdef가 됩니다.  그냥 앞의 문자열과 뒤의 문자열이 합쳐지는 것입니다!

 

 

다음은 리스트입니다. 튜플/딕셔너리는 잠시 접어두고  리스트만 보고 다음 글로 넘어갈게요.

리스트는 C/C++에서 배열과 동일합니다. 리스트를 비워두고 입력받는 방법은 지금은 말고 리스트와 관련된 문법만

리뷰해보겠습니다.

 

hello = ['1','2','3','4','5']  이렇게 리스트가 있다합시다.

근데, 생각해보니 우리는 배열(리스트)의 인덱스가 0부터 시작한다는 사실을 까먹고 있었습니다. 그래서 가장 뒤 원소를 지우고 제일 앞에 0을 추가하고자 합니다.

 

이럴 때 사용되는 리스트 문법은 2가지가 있습니다.

 

1. remove

위 리스트에서 원소 5를 빼고자할때는 hello.remove('5')를 해주면 삭제가 되구요.

 

2. insert

hello.insert(0,'0')를 하면 됩니다.  앞에 0은 인덱스를 가리키고, 뒤에 '0'은 0번째 인덱스에 박아넣어라! 라는 말입니다.

반응형
반응형

 

0. 서론

- 저는 SCSA전형엔 2번째 도전이었고, 처음에는 삼성전자 DX (CE/IM)을 지원하고 면접에서 탈락하였습니다.

그 후, 2번째 도전 때는 삼성SDS로 지원하여 검진을 마치고 대략 1달 뒤, 입과를 앞두고 있습니다.

 

스펙

1. 학교 : 중경외시 라인

2. 전공 : 물리학과

3. 학점 : 3.64 (전공 3.53)

4. 경력 : 외국계 반도체회사 Test엔지니어 8개월 (SW직무 O) ,

LG디스플레이 CTO소속 연구원 5개월 (SW직무 X)

    → 삼성에 지원당시 LGD는 기재 하지않았음.

5. 기타 : 네이버 블로그 IT인플루언서 활동 소개

6. 코딩 독학 기간 : 대략 2년 (타기업 코딩테스트 7회 중 6회 통과 : LG CNS제외 다 제조기업. LG전자,한화솔루션,현대모비스,현대자동차 등등)

 

 

 

1. 자소서

삼전DX SCSA를 쓸 때는 서류는 합격했지만, SDS와는 결이 다른 회사기도 했고 서류복붙은 하기가 싫었습니다.

SCSA의 특성상 자소서 방향은 일반 공채랑 다르게 접근하고 싶었기 때문입니다.

 

SCSA는 관심있는 분들은 이미 다 아시겠지만 비전공자를 대상으로 6개월 간 교육을 거쳐 정규직으로 전환(사실상 거의 100% 전환)까지의 절차가 있는 굉장히 긴 전형입니다.

 

따라서, 이 긴 시간을 잘 따라올만큼 SW에 진심인지 / 정말 단순흥미가 아닌 진지한 커리어를 생각한 것인지? 를 보여줘야합니다. 이번 SDS에서의 컨셉은 이렇게 잡고 글을 썼습니다.

 

 

1번 항목) 지원동기 및 입사 후 포부

→ 지원동기 컨셉 : 나는 sw에 관심이 3학년 때부터 있었고, 스스로 공부해오면서 IT블로그 운영 및 토이프로젝트도 몇개 해봤다. 근데 독학에 한계가 느껴져서 결국 체계적인 교육을 한번 받아야겠다는 필요성을 깨달았다.

근데, 내가 토이플젝하면서 관심있던건 클라우드 시장의 성장세였고,  클라우드 시장에서 영향력이 있으면서도 나 같은 비전공자에게 교육기회를 제공해주는 곳은 삼성SDS뿐이었다. 그래서 지원했다.

 

→ 입사 후 포부 : 나는 클라우드의 미래 가치를 남들보다 잘 알고 있다. 코로나 이후 비대면 근무의 활성화는 곧 sw열풍을 불러일으켰고 it스타트업에 필요한 IT자원 및 인프라 / 금융&공기업의 온프레미스 체제 → 클라우드 전환 검토 트렌드를

확인했을 때, 핀테크 기업 + 금융권 + 공기업을 모두 겨냥한 "금융클라우드 DevOps"가  현 IT시장에서 최상위 포지션이 될 것을 느꼈다. 삼성SDS는 최근에 금융클라우드로의 투자도 주력하는만큼 이 포지션을 목표로 내 꿈을 펼치겠다.

 

 

1번 항목은 위와 같은 컨셉으로 작성하였습니다. 

 

Q1. 뭘 하고싶은지 세부 직무가 없는데 반드시 정해야하나요?

A1. 그건 아닙니다. 세부 직무 안쓰고 서류붙은 분들은 많아요. 다만, 저같은 경우 면접에서 관심을 많이 보이셨습니다. 임원/직무 둘다 클라우드를 하고싶다한 이유 / 클라우드의 미래 가치 / 데브옵스가 뭐냐 / 데브옵스의 비중 등등 예상 가능한 질문들 선에서 그대로 질문이 들어왔기에  저는 쓰는 걸 추천합니다. 우리가 질문할 소스를 던져주자는 겁니다.

 

Q2. 내가 이 직무를 하고싶다해도 다른데로 배치될 수도 있잖아요?

A2. 이미 예상질문을 하나 알게되신겁니다. 저는 그에 대한 대답도 준비했었습니다. 

이미 여러분들도 다 느끼셨을 답변일 겁니다.

IT기업 특성상 SW업무는 이런저런 포지션들과 유기적으로 다 연결이 되어있습니다. 따라서, 배치받게 될 업무가 생각했던것과 달라도 자리를 지키며 열심히 일한다면 언젠가 업무의 바운더리가 넓어질 거란 것도 알고, 삼성은 그런 기회를 주는 회사인 것도 알고있습니다.  라고 준비했었습니다.

 

 

 

2번 항목) 성장과정

→ 1500자나 되는 어려운 항목이지만, 저는 1100자만 적었습니다. 그리고 딱 한 가지 주제만 썼습니다. 대부분이 1500자 가까이 채우고 2가지 주제, 많게는 3가지를 씁니다.

다만, 중요한 건 양보단 질입니다. 면접관들이 보고자 하는건 성장을 하게 된 역경/고난의 횟수가 아니라  그 과정을 어떻게 이겨내면서 성장한건지입니다.

 

계단식 성장이라는 말이 있습니다. 처음에는 모든게 쉬우니 금방금방 자신감도 붙고 배워가는게 재밌을 시기입니다.

그러나, 어느 순간 정체되는 기간이 옵니다. 저는 이러한 기간을 역경으로 잡았고, 정체기간을 뚫기 위한 노력들을 서술했습니다. 이게 결국 SCSA에서도 유사하게 마주할 어려움이니까, 굉장히 설득력이 있는 내용이라 판단했기 때문입니다.

 

 

 

3번 항목) 사회이슈

→ 사회이슈는 꼭 현업과 관련된 이야기를 쓰지 않아도 됩니다.

삼성전자 DX때는 유튜버/블로거와 같은 1인 미디어 컨텐츠 주제를 썼었고

삼성SDS때는 A.I 버추얼 인플루언서를 주제로 썼었습니다.

얘는 이번 면접땐 질문도 안들어왔고, 삼전 DX 창의성 면접때도 안들어왔습니다.

 

 

 

2. GSAT

삼성전자 DX : 38/42  (맞은거/푼거)

삼성SDS : 41/46  (맞은거/푼거)

 

서류가 발표나고 시작했으며, 해커스 파랭이교재 + 봉투모의고사 1,2,3회로만 준비했습니다. 삼전 / SDS모두 서류붙고나서 준비했습니다. 2~3주정도의 시간을 주니까 충분합니다.  단, 교재는 품절될까봐 미리 사놓긴 했었습니다 ㅋㅋ

GSAT 컷은 모릅니다. 다만, 35개 아래는 못본거 같습니다. 35개 넘으면 면준하세요.  GSAT이후부턴 면접까지 금방이니

35개 넘으면 그냥 아묻따 면준 ㄱㄱㄱ 안하시면 하루하루를 허비한걸 정말 후회하시게 될겁니다 ㅠ

 

저도 41개 맞은거 확인하고 그냥 바로 기존에 삼전DX때 받았던 PPT양식 그대로 활용해서  GSAT발표 날에 이미 PPT다 완성하고 대본 짜고 있었습니다.

 

 

얘기가 좀 샜는데, GSAT 나름의 풀이 팁을 드리자면

자료해석의 경우는 18,19,20번부터 풀었습니다. 여긴 단순계산 (수열) 쪽이라 계산실수만 안하면 답이 딱 나오는 문제들입니다. 자료해석처럼 선지 하나하나 비교해갈필요도 없기에 가장 먼저 풀었습니다.

 

그 후, 1,2번 방정식문제 풀었고 한번에 안풀리면 무조건 넘어갔습니다. 그 뒤로 자료해석은 항상 선지 3번부터 확인했습니다. 1번이 답인 경우는 잘 없다는걸 이미 알고 있었고,  선지는 3->4->5->2->1 / 3->2->4->5->1 / 3->4->2->5->1  이렇게

3가지 순서들로만 확인해갔습니다. 운이 좀 따르면 바로 답을 찾기도 하고, 실제 GSAT때 운이 좋기도 했던거 같습니다.

 

자료해석은 이런 풀이순서만 지킨게 다입니다. 20문제 모두 다 풀었고 1분 남았었습니다. (채점 결과 16/20 ㅋㅋ??)

 

조건추리는  제가 한가지 명심한게 있습니다.  범인찾기 / 참,거짓 문제는 무조건 제일 마지막에 풀고 다 푸는걸 목표로 하지말자였습니다.

 

저는 도형/도식추리 -> 독해 -> 명제 -> 조건추리 식으로 풀었습니다. 조건추리 전에 다른 유형들은 모두 다 맞히는걸 목표로 했고 남는 시간동안 조건추리는 못해도 4문제 이상은 맞히면 성공한 GSAT이다! 라고 판단했습니다.

 

채점 결과는 25/26이었습니다.

 

 

 

 

3. 임원 면접 / 직무 면접

면접은 GSAT 합격하고 나서 1주일 뒤였습니다. PPT제출기한은 4일뿐이었습니다.

면접 순서는 다 랜덤이고  저는  약식GSAT+인성검사 -> 임원 면접 -> 직무 면접 순이었습니다.

 

임원 면접은 3대1이었고

면접 내용 자체는 다 대외비입니다. 면접 시간은 20분이었고 저는 얼추 다 채운거 같습니다. 한 17~18분정도 본거같아요.

100% 자소서 기반으로만 물어보셨고,

제가 하고싶어하는 직무를 총괄담당하시는 분들이 들어오셔서  운이 매우 따른 면접이었다.. 라고 말할 수 있겠습니다..!

긍정시그널로 가득했었고  덕분에 직무면접 대기 시간 동안에도 자신감 갖고 문제 풀었던거 같습니다.

 

직무 면접도 3대1입니다.  사전 문제 풀이시간 50분 주어지고, 시간이 끝나면  면접실로 들어가서 PPT제출한거 발표 + 문제 풀이 발표 + 질의응답으로 총 20분정도 소요합니다.

 

말이 50분이지, 코딩 공부 해오신분들이라면 10분 컷 가능합니다. 아마, 문제는 쉽지만 대본 짤 시간까지 고려해서 50분 주신거 같습니다.  백준/삼성SW Expert/프로그래머스 등등 열심히 푸세요.  문제 보고  어? ㅋㅋㅋ 할겁니다.

 

 

면접 끝나고나면 시그널 얘기랑  임원 vs 직무  이야기 많이 할텐데,  한 가지 확실한건  면접 끝나고 나왔을 때 느낀 본인의 감정만이 진짜입니다!  유례없던 면접 발표 지연으로  저도 많이 불안했었지만, 결국 첫 느낌이 맞더군요.

 

 

 

2022 삼성그룹 전체 하반기 면접 기간은 11월 3일(삼전 인턴분들 면접) ~ 11월 18일까지 였습니다.

저는 11월 9일 면접자였습니다. 그리고 발표는 12월 9일에 나왔고 화면이 바뀐건 오후 1시 37분 /

발표는 오후 5시 13분에 나왔습니다.

 

* 내년에 준비하시는 분들이 모두 시그널 얘기부터 화면 바뀌는 시간, 몇시에 발표했는지 등등 다 궁금해하실테니 ㅎ

기록해놨습니다 ^^7 

 

 

제 검진은 12월 13일이었고, 이건 계열사와 직무마다 다 다릅니다. 저같이 소수티오 / 전자가 아닌 계열사인 경우는

빨리 볼거에요.

 

+ SCSA를 준비하시는 분들이 또 궁금해하실건  비대면 vs 대면일텐데  저희 기수 때부터 다시 대면으로 전환하려는거 같습니다. 역삼말고 신사옥에서 한다는 얘기가 있고, 아직 지도에도 안 뜰 정도로 새거인듯 합니다. 위치는 건대~ 어린이대공원역 근처인거 같아요.

 

이제 교육 잘받고 최종 전환 글 쓰는 날까지 코딩공부 잘하고 오겠습니당

반응형
반응형

회문 (팰린드롬)은 앞뒤로 읽어도 똑같은 단어를 말합니다.

문자열 구현 중 기초역량을 체크하기 위해 항상 등장하는 문제인데, c++로 풀어보았습니다.

#include <iostream>
#include <string>

using namespace std;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	
	int T;
	cin >> T;
	int i,j=0;
	int cnt = 0;
	string s;
	
	while(T>0)
	{
		cin >> s;
		int t = s.size();
		for (i=0; i<t/2; i++)
		{
			if (s[i]==s[t-i-1])
			{
				cnt++;
			}
			
			else
			{
				cnt = 0;
			}
		}
		
		if (cnt!=0)
			cout << "#" << j+1 << " " << "1" << "\n";
		else if (cnt==0)
			cout << "#" << j+1 << " " << "0" << "\n";
		j++;
		T--; 
	}
	
	return 0;
}

C++로 넘어오면서 참 좋았던게 C언어 때와 달리 문자열을 다루기가 넘 쉬워져서 행복하네요.

string 헤더파일을 사용해서 s.size()를 구해준게 키 포인트입니다.  (C언어의 strlen과 동일)

 

회문 판별은 cnt을 이용해서 앞뒤가 같을 때마다 카운팅을 해주는 것이고 만약 동일하지 않다면 cnt를 하지 않습니다.

그렇게해서 cnt==0인 애는 회문이 아닌걸로, cnt!=0인 애는 회문인걸로 판별하였습니다.

 

뭔가 로직이 이상해서 틀릴거 같았는데 풀리긴하네요.

 

 

반응형
반응형

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

 

2751번: 수 정렬하기 2

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

해당 문제는 수의 개수가 100만까지 있다. N^2로 하면 시간초과가 날게 뻔하다. 정렬 알고리즘 중에서 최대 NlogN까지의 시간복잡도를 갖는 애로 가야한다.

 

1) 퀵소트로 풀어봤다.

#include <stdio.h>

void quick (int arr[], int start, int end)
{
	if (start>=end)
    {
    	return;
    }
    
    int key = start;
    int i = start+1;
    int j = end;
    int change;
    
    while (i<=j)
    {
    	while (arr[key]<=arr[i])
        {
        	i++;
        }
        
        while (arr[j]>arr[key] && j>key)
        {
        	j--;
        }
        
        if (i>j)
        {
        	change = arr[j];
            arr[j] = arr[key];
            arr[key] = change;
        }
        
        else
        {
        	change = arr[j];
            arr[j] = arr[i];
            arr[i] = change;
        }
    }
    
    quick (arr,start,j-1);
    quick (arr,j+1,end);
}

int main()
{
	int i,number = 0;
	scanf("%d",&number);
	int arr[number];
	for (i=0; i<number; i++)
	{
		scanf("%d",&arr[i]);
	}
	quick (arr, 0 , number-1);
	for (i=0; i<number; i++)
	{
		printf("%d\n",arr[i]);
	}
	return 0;
}

근데 퀵소트로 푸니까 시간초과가 나왔다. 아마 퀵소트의 경우는 Best, Avg케이스는 NlogN이지만 Worst케이스는 N^2가 나올 수 있기 때문인 것 같다.

 

따라서, NlogN 정렬 중 합병정렬이나 힙 정렬로 접근해보고자 한다.

 

 

-> 합병정렬

#include <stdio.h>

int sorted[1000000];

void merge (int arr[], int start, int mid, int end)
{
	int i = start;
	int j = mid+1;
	int k = start;
	
	while(i<=mid && j<=end)
	{
		if (arr[i]<=arr[j])
		{
			sorted[k] = arr[i];
			i++;
		}
		else
		{
			sorted[k] = arr[j];
			j++;
		}
		k++;
	}
	
	if (i>mid)
	{
		int t;
		for (t=j; t<=end; t++)
		{
			sorted[k] = arr[t];
			k++;
		}
	}
	
	else
	{
		int t;
		for (t=start; t<=mid; t++)
		{
			sorted[k] = arr[t];
			k++;
		}
	}
	int t;
	for (t=start; t<=end; t++)
	{
		arr[t] = sorted[t];
	}
	
}

void merge_sort (int arr[], int start, int end)
{
	if (start<end)
	{
		int mid = (start+end)/2;
		merge_sort (arr,start,mid);
		merge_sort (arr,mid+1,end);
		merge (arr,start,mid,end);
	}
}

int main()
{
	int i,number = 0;
	scanf("%d",&number);
	int arr[number];
	
	
	for (i=0; i<number; i++)
	{
		scanf("%d",&arr[i]);
	}
	
	merge_sort (arr,0,number-1);
	for (i=0; i<number; i++)
	{
		printf("%d\n",arr[i]);
	}
	
	return 0;
}
반응형
반응형

 

풀이에 사용한 언어 : C언어

그리디 알고리즘
- 현재 주어진 Step만을 기준으로 하여, 최적의 해를 구하는 알고리즘이다.
다만, 매 Step마다 최적의 해를 구했다해도 최종 결과는 최적의 해가 아닐 수 있다. 그래서 불완전한 알고리즘이며 특수한 경우에만 그리디 알고리즘을 쓴다.

대표적인 예제가 거스름돈이다. 우리가 맥도날드에서 상하이스파이시버거세트를 산다하자. 한 때, 굉장히 좋아했는데 이사한 집 근처에 맥날이 없어서 가격이 기억안나지만 대충 5500원이였던 것 같다.
10000원을 지불하고 4500원을 거슬러 받는다 하면, 일반적으로 1000원 4장, 500원 1개로 총 5번의 거스름을 받는게 맞다. 화폐는 그 단위가 5000,1000,500,100... 이런 식으로 정해져 있고 내림차순 (혹은 오름차순)이기 때문에 그리디를 적용해도 괜찮다.

아래 코드 내용은, 돈을 입력받았을 때, (예를 들면 3100원이라 하자) 500원,100원,50원,10원만 갖고 있을 때 가장 최소한으로 거스름을 한 결과를 구현하고자 했다.

물론 아래 코드는 실행해보면 잘못되었음을 알 수 있다.

#include <stdio.h>

int main()
{
	int money;
	scanf("%d",&money);
	int n,m,k,l=0;
	
	while(money>0)
	{
		money = money%500;
		n = money/500;
		
		if (money<500)
		{
			money = money%100;
			m = money/100;
			if (money<100)
			{
				money = money%50;
				k = money/50;
				if (money<50)
				{
					money = money%10;
					l = money/10;
				}
			}
		}
		printf("%d",n+m+k+l);
		
	}
	
	return 0;
}

그럼 왜 틀렸는지 분석을 해봤는데, 단순히 코드의 순서가 잘못되었다고 판단 중이다.
보면 %연산자를 먼저한 값을 money에 집어넣고 그 다음 몫연산자를 카운팅했으니 값이 이상하게 나올 수 밖에 없다.
또한, if문은 필요가 없다. 반복을 수행하면서 알아서 500원 이하면 100으로 넘어갈테니까.

#include <stdio.h>

int main()
{
	int cnt = 0;
	int money;
	scanf("%d",&money);
	
	while (money>0)
	{
		cnt += money/500;
		money = money%500;
		
		cnt += money/100;
		money = money%100;
		
		cnt += money/50;
		money = money%50;
		
		cnt += money/10;
		money = money/10;
	}
	
	printf("%d",cnt);
	
	return 0;
}

그래서 재구성해본 결과는 이러하다.

잘 나온다. 4700원을 먼저 500원으로 거스르면 9번이고 나머지 200원은 100원으로 거스르면 2번이니까 총합 11번이다.
결과는 같다.

반응형

+ Recent posts