https://swexpertacademy.com/main/solvingProblem/solvingProblem.do
N X N 크기의 단어 퍼즐을 만들려고 한다. 입력으로 단어 퍼즐의 모양이 주어진다.
주어진 퍼즐 모양에서 특정 길이 K를 갖는 단어가 들어갈 수 있는 자리의 수를 출력하는 프로그램을 작성하라.
[예제]
N = 5, K = 3 이고, 퍼즐의 모양이 아래 그림과 같이 주어졌을 때
길이가 3 인 단어가 들어갈 수 있는 자리는 2 곳(가로 1번, 가로 4번)이 된다.
[제약 사항]
N은 5 이상 15 이하의 정수이다. (5 ≤ N ≤ 15)
K는 2 이상 N 이하의 정수이다. (2 ≤ K ≤ N)
[입력]
입력은 첫 줄에 총 테스트 케이스의 개수 T가 온다.
다음 줄부터 각 테스트 케이스가 주어진다.
테스트 케이스의 첫 번째 줄에는 단어 퍼즐의 가로, 세로 길이 N 과, 단어의 길이 K 가 주어진다.
테스트 케이스의 두 번째 줄부터 퍼즐의 모양이 2차원 정보로 주어진다.
퍼즐의 각 셀 중, 흰색 부분은 1, 검은색 부분은 0 으로 주어진다.
[출력]
테스트 케이스 t에 대한 결과는 “#t”을 찍고, 한 칸 띄고, 정답을 출력한다.
(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)
입력
10
5 3
0 0 1 1 1
1 1 1 1 0
0 0 1 0 0
0 1 1 1 1
1 1 1 0 1
5 3
1 0 0 1 0
1 1 0 1 1
1 0 1 1 1
0 1 1 0 1
0 1 1 1 0
…
출력
#1 2
#2 6
...
t = int(input())
for i in range(1, t + 1):
res = 0
l, k = map(int, input().split()) # 크기와 자리수
_map = [input().replace(" ", "") for _ in range(l)] # 입력받는 퍼즐
for m in _map:
if "1" * k in m.split("0"):
res += 1
#전치행렬 만들때 list(zip(*행렬))
for m in list(zip(*_map)):
if "1" * k in "".join(m).split("0"):
res += 1
print(f"#{i} {res}")
처음에 입력받은 _map
에서 공백을 제거하는 데 꽤 애좀 썼다..(공백을 제거 안하면 세로길이의 k를 찾기 위해 행렬을 반전할 때 공백이 들어가기 때문)
문자열에서 공백을 제거할 때는 replace()
를 이용하면 된다. => 문자열.replace(" ", "")
또한 zip을 이용해 전치행렬을 만들 수 있다. (참고)
zip(*행렬)
예를들어 [[1,2,3],[4,5,6]]
과 같은 행렬이 있을 때 *
로 언패킹하면 (1,2,3)
과 (4,5,6)
이 나온다. 이를 zip()
으로 묶어주니 (1,4), (2,5), (3,6)
이 나오는 것!
한시간동안이나 풀었는데 결국....
t = int(input())
for tc in range(1, t + 1) :
n, k = map(int, input().split())
data = [list(map(int, input().split())) for _ in range(n)]
result = 0
# 가로 확인
for i in range(n) :
cnt = 0
for j in range(n) :
if data[i][j] == 1 :
cnt += 1
if data[i][j] == 0 or j == n -1 :
if cnt == k :
result += 1
if data[i][j] == 0 :
cnt = 0
# 세로 확인
for i in range(n) :
cnt = 0
for j in range(n) :
if data[j][i] == 1 :
cnt += 1
if data[j][i] == 0 or j == n - 1 :
if cnt == k :
result += 1
if data[j][i] == 0 :
cnt = 0
print('#%d %d' % (tc, result))
https://unie2.tistory.com/1001
한줄을 모두 검사하면서 1을 만나면 카운트를 높이고 0을 만나거나 마지막 열일 때 1이 k개수만큼 있으면 결과+1, 0을 만났으면 카운트를 날려버린다.
전치행렬에서 똑같이 검사한다.
5번 7번 9번 테스트케이스에서 오류가 난다...
그런데 댓글 안보고 애초에 저렇게 한건데 왜 안되지?
+)input output분석해봤는데 zip이 행 순서에 맞게 제대로 안됨..
역시 하드코딩이 최고다..;
1028 ++) 순서에 맞게 안된 게 아니라 "1"*k
가 있는지 탐색 후 res
를 1번만 카운트하니까 그 꼴이 난 것이다!!
각 행의 문자열을 0으로 split
한 후 거기에 "1"*k
가 몇 개 있는지 탐색해야함
t = int(input())
for i in range(1, t + 1):
res = 0
l, k = map(int, input().split()) # 크기와 자리수
_map = [input().replace(" ", "") for _ in range(l)] # 입력받는 퍼즐
for r in _map:
for m in r.split("0"):
if m == "1" * k:
res += 1
# 전치행렬 만들때 list(zip(*행렬))
for r in list(zip(*_map)):
for m in "".join(r).split("0"):
if m == "1" * k:
res += 1
print(f"#{i} {res}")
첫 번째 시도에서 오류를 다듬은 코드이다.
어쨌거나 저쨌거나 삼중반복문인건 변하지 않는군