본문 바로가기

백준 온라인 저지 (BOJ) 문제풀이

백준 온라인 저지 14492 부울행렬의 부울곱

문제

문제를 출제하던 욱제는 갑자기 괴랄한 문제를 내고 싶어졌다. 불행하게도, 이번 대회에는 프로그래밍 뉴비들이 많기 때문에 그럴 수는 없었다. 하지만 욱제는 신입생들을 괴롭히고픈 욕망을 포기할 수 없었다.

‘하하! 과연 신입생들이 이 문제를 풀 수 있을까?’

문제는 간단하다. N*N 크기의 두 부울행렬(0과 1로만 이루어진 행렬) A=[aij]와 B=[bij]가 주어졌을 때, 두 행렬에 대해 부울곱 연산을 수행한 행렬 C=[cij]에 나타나는 1의 개수를 세는 것이다. 부울곱 연산은 아래와 같이 수행된다.

cij = (ai1∧b1j)∨(ai2∧b2j)∨...∨(ain∧bnj)

xij는 X행렬의 i행j열 원소를 뜻하며 ∧는 논리곱(AND), ∨는 논리합(OR) 연산을 나타낸다. 자, 어서 코딩하자!

입력

첫째 줄에 행렬의 크기 N(1<=N<=300)이 주어진다. 이후 N개의 줄에 N*N의 부울행렬 A=[aij]와, 다음 N개의 줄에 N*N의 부울행렬 B=[bij]가 주어진다.

출력

A☉B를 연산한 행렬 C에서 나타나는 1의 개수를 세어서 출력한다.

 

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
#include <iostream>
 
using namespace std;
bool A[301][301], B[301][301];
 
bool cal(int i, int j, int n) {
    for (int x = 1; x <= n; x++)
        if (A[i][x] && B[x][j])
            return true;
    return false;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, s = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cin >> A[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cin >> B[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (cal(i, j, n))s++;
    cout << s << '\n';
    return 0;
}
cs

 

A or B or ... or Z 라는 논리식이 있을 때 A,B ... Z 중 아무거나 하나라도 참이라면 논리식이 참이라는 성질을 이용했다.

 

따라서 cij = (ai1∧b1j)∨(ai2∧b2j)∨...∨(ain∧bnj) 이므로 각각의 항 중에 하나라도 참이라면 true를 반환하고 전부 거짓인

 

경우에는 false를 반환하도록 함수를 구현해서 해결했다.