본문 바로가기
Problem Solving/SWEA

[ SWEA ] D2 - 1983, 1979, 1976, 1974 - python 문제풀이

by IM조이 2021. 6. 24.

1983 조교의 성적매기기

scores = ["A+","A0","A-","B+","B0","B-","C+","C0","C-","D"]
for tc in range(int(input())):
    N,K = map(int, input().split())
    # i번째 점수는 (i+1)번 학생의 점수
    info = [list(map(int, input().split())) for _ in range(N)]
    student_scores = []
    for i in range(N):
        total = info[i][0]*0.35 + info[i][1]*0.45 + info[i][2]*0.2
        student_scores.append([total, (i+1)])
    student_scores.sort(key=lambda x:x[0],reverse=True)
    for rank in range(N):
        if student_scores[rank][1] == K:
            print("#{} {}".format(tc+1,scores[rank//(N//10)]))
            break

 

1979 어디에 단어가 들어갈 수 있을까

def check(li,n,s,e,k):
    global cnt
    # k자리만큼의 공간을 발견했다면? 내 앞이나 뒤가 0인지 아닌지 확인해야 함
    if li[s][e:e+k]==[1]*k:
        # 현재 맨 뒤일 경우 : 앞만 확인하면 됨
        if e+k == n and e != 0 and li[s][e-1] == 0:
            cnt += 1
        # 현재 맨 앞일 경우 : 뒤만 확인하면 됨
        elif e+k < n and e == 0 and li[s][e+k] == 0:
            cnt += 1
        # 중앙에 있을 경우 : 앞 뒤를 다 확인해야 함
        elif e+k < n and e != 0 and li[s][e+k] == 0 and li[s][e-1] == 0:
            cnt += 1
        return
    return

for tc in range(int(input())):
    N,K = map(int, input().split())
    puzzle = [list(map(int, input().split())) for _ in range(N)]
    puzzle_rev = [[puzzle[m][n] for m in range(N)] for n in range(N)]
    cnt = 0
    for i in range(N):
        for j in range(N):
            check(puzzle,N,i,j,K)
            check(puzzle_rev, N, i, j, K)
    print("#{} {}".format(tc+1,cnt))

또 다른 방법으로는 0을 기준으로 split을 한 뒤 1의 개수(count)가 k개인 묶음의 개수를 세는 것.

 

1976 시각덧셈
처음에는 그냥 생각한대로 풀어서 통과했는데, 좀 더 생각해보니 지금 SWEA의 테스트케이스에서는 잡아내지 못하는 경우가 있어서 좀 더 개선해서 코드를 짜 보았다.

# 통과는 되지만, 완벽하지 않은 코드
for tc in range(int(input())):
    h1,m1,h2,m2 = map(int, input().split())
    hour = (h1+h2)%12 + (m1+m2)//60
    minute = (m1+m2)%60
    print("#{} {} {}".format(tc+1, hour, minute))

만약 테스트케이스가 12 00 12 00 이런식으로 들어온다면, 답은 = 24=> 12로 표현되어야 한다. (문제 조건에 따르면 시간은 1~12만 가능하기때문에 답이 12 0 이 나와야) 하지만, 위에 짠 코드대로라면 0 0 이 나온다. 따라서 더 완벽하게 예외처리를 해준다면 다음 코드가 더 정확하다.

for tc in range(int(input())):
    h1,m1,h2,m2 = map(int, input().split())
    hour = (h1+h2)%12 + (m1+m2)//60
    minute = (m1+m2)%60
    if h1==12 and h2==12 and m1+m2 < 60:
        hour = 12
    print("#{} {} {}".format(tc+1, hour, minute))
    
'''
확인용 테스트케이스

    3
    12 00 12 00
    12 20 12 30
    12 30 12 31  
    
답은

    12 0
    12 50
    1 1

'''

 

1974 스도쿠 검증

Idea 1. 가로, 세로 조건을 구현하기가 쉽기 때문에 먼저 확인하고, 가로 세로 조건을 만족하는 경우에만 작은 네모 조건을 확인하기

Idea 2. 각 자리의 인덱스로 배열에 접근해 값을 판단할 수 있기 때문에, 어떻게 인덱스로 접근해야 저 9개의 네모에 순차적으로 접근할 수 있을 지 파악해 규칙을 찾아내기

for tc in range(int(input())):
    sudoku = [list(map(int, input().split())) for _ in range(9)]
    sudoku2 = list(zip(*sudoku))

    result = 1
    garo = True
    sero = True

    # 가로&세로 검증
    for i in range(9):
        if garo == False or sero == False:
            break
        if len(set(sudoku[i]))!=9 or sum(sudoku[i])!=45:
            garo = False
            break
        if len(set(list(sudoku2[i]))) != 9 or sum(sudoku2[i])!=45:
            sero = False
            break

    # (가로&세로 검증O) 작은네모 검증
    if garo == True and sero == True:
        error_flag = False
        for i in range(9):
            tmp = 0
            for j in range(9):
                tmp += sudoku[3*(i//3)+j//3][3*(i%3)+j%3]
            if tmp != 45:
                error_flag = True
                break

    if garo == False or sero == False or error_flag:
        result = 0
    print("#{} {}".format(tc+1, result))

함수를 사용하지 않았을 때

단, 이때 함수를 사용해서 가로세로 조건을 만족하지 않는 경우 바로 0으로 리턴시켜버리면 코드가 더 깔끔하고 빠르다

def prove(li1,li2):
    for i in range(9):
        if len(set(li1[i])) != 9 or len(set(li2[i])) != 9:
            return 0
    for i in range(9):
        tmp = 0
        for j in range(9):
            tmp += li1[3*(i//3)+j//3][3*(i%3)+j%3]
        if tmp != 45:
            return 0
    return 1

for tc in range(int(input())):
    sudoku = [list(map(int, input().split())) for _ in range(9)]
    sudoku2 = [[sudoku[i][j] for i in range(9)] for j in range(9)]
    print('#{} {}'.format(tc+1,prove(sudoku,sudoku2)))

함수를 사용했을 때 - 코드도 깔끔, 실행시간도 더 빠름

 

댓글