티스토리 뷰

Haskell-PS

Purple Haskell(2)

jwvg0425 2019. 11. 22. 23:15

https://codeforces.com/group/DEuKcKDfls/contest/227547

오늘 연습

A.Flipping Game

길이 n(<=100)인 0,1로만 구성된 배열이 주어지고, 여기서 연속한 구간을 하나 아무거나 골라 뒤집을 수 있다고 했을 때 1의 개수를 최대화하는 문제다.

n 제한이 굉장히 작으므로 그냥 모든 가능한 배열 만들어서 그 중 제일 큰 걸 구했다. 이런 거 할 땐 list comprehension이 제일 편한 듯

B. Candy Bags

1 ~ n^2(n은 짝수, n <= 100)까지의 수를 합이 동일한 n개의 배열로 나누는 문제다. 맨앞 맨 뒤에서 각각 n/2개씩 가져오는 걸 반복하면 되는데, 구현을 어떻게 하면 좋나 좀 고민이 됐다. 내가 생각한 과정은 다음과 같다.

1. 일단 1 ~ n^2으로 구성된 배열을 만든다

2. n/2 사이즈로 전부 분할한다

3. 맨 앞, 맨 뒤에서 한 덩이씩 가져와서 n개짜리 배열을 만든다

아주 마음에 들진 않지만 무난한 듯. n/2 사이즈로 분할하는게 조금 짜증났다

C.  Levko and Table

n*n( n <= 100) 사이즈 행렬을 만드는데, 행렬의 각 행과 열이 전부 합이 k가 되게 만드는 문제다. 말이 그렇지 주대각선에 k 박으면 무조건 행, 열 각각 전부 합이 k가 되므로 나머진 전부 0으로 채워져있고 주대각선에 k 들어간 행렬을 만들면 된다.

나는 [k,0,0,0,...] 으로 만들어진 배열을 만들고 이걸 iterate 함수를 이용해 앞에 0을 덧붙이며 n개씩 자르는 식으로 구현했다. 이런거 짤 땐 iterate가 정말 강력한 것 같다

D. Levko and Permutation

1~n까지 숫자로 이루어진 길이 n 순열에 대해, i번째 숫자가 Pi라고 하자. gcd(i, Pi) > 1인 위치가 k개가 되는 순열을 아무거나 하나 찍는게 문제다.

방법은 되게 다양하게 있을텐데, 나는 gcd(x, x+1) = 1, gcd(a, a) = a 인 걸 이용해서 풀었다. k = n인 경우는 불가능하니 -1, k = n -1인 경우는 [1..n] 그대로 출력, 그 외의 경우는 2 ~ k+1 번 위치에 숫자 그대로 둬서 gcd(i, Pi) > 1인거 k개를 확보한 후 나머지 위치는 전부 gcd가 1이 되게 배치하는 식으로 구했다.

경우만 정리하고 나면 구현하긴 간단한 듯. 예전에 C++로 짰을 땐 좀 다른 방식으로 풀었었는데 그 방식은 haskell로 짜긴 안 적합했다. 함수형 언어로 구현하기 쉬운 형태의 답안을 잘 고민하는 연습도 필요할 것 같다

 

암튼 다 푸는데 대충 40분쯤 걸린 것 같은데, 중간중간 딴짓한 거 감안해도 좀 너무 오래 걸림. 1년전에 C++로 풀었을 때 다 푸는데 30분쯤 걸렸으니, 이거 C++로 푼 기록들 보고 대충 비슷한 시간 안에 문제들 해결하는 걸 목표로 연습을 해야겠다. 아직은 haskell로 깔끔하게 짤 수 있는 방법도 바로 안 떠오르고, 방법을 생각해도 그걸 빠르고 정확하게 코드로 옮기는 게 잘 안 되는 것 같다.

'Haskell-PS' 카테고리의 다른 글

Purple Haskell (1)  (0) 2019.11.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함