집합 방정식

시간 제한2초메모리 제한64 MB

요약
합집합, 교집합, 차집합, 대칭차를 포함한 집합 방정식을 파싱하고 각 원소별로 미정 변수들의 소속 여부를 결정해 방정식을 만족시키는 사전식 최소 해를 구하거나 해가 없음을 판정합니다.
난이도

보통10점 중 6점

유형
시뮬레이션, 구현, 비트 연산
정답자
아직 제출이 없습니다

문제

Nick은 집합론을 공부하다가 집합 방정식을 정의했다. 각 집합 변수는 고정된 전체집합 Ω\Omega의 부분집합을 나타낸다. 집합 변수에는 다음 네 가지 연산이 정의된다.

  • 교집합 ∩\cap: A∩B={ x:x∈A∧x∈B }A \cap B = \{\, x : x \in A \wedge x \in B \,\}
  • 합집합 ∪\cup: A∪B={ x:x∈A∨x∈B }A \cup B = \{\, x : x \in A \vee x \in B \,\}
  • 차집합 −-: A−B={ x:x∈A∧x∉B }A - B = \{\, x : x \in A \wedge x \notin B \,\}
  • 대칭차집합 △\triangle: A△B=(A−B)∪(B−A)A \triangle B = (A - B) \cup (B - A)

연산의 우선순위는 높은 것부터 낮은 것 순으로 교집합, 합집합, 차집합, 대칭차집합이다. 괄호는 일반적인 방식대로 우선순위를 바꾼다.

방정식은 다음 문법으로 텍스트로 저장된다.

<ws>       -> ( space | tab )*
<char>     -> 'A' | 'B' | ... | 'Z' | 'a' | 'b' | ... | 'z'
<var>      -> <char> <char>*
<expr>     -> <var>
            | <expr> <ws> <operator> <ws> <expr>
            | '(' <ws> <expr> <ws> ')'
<operator> -> '+' | '*' | '-' | '^'
<equation> -> <expr> <ws> '=' <ws> <expr>

연산 ∪\cup, ∩\cap, −-, △\triangle는 각각 토큰 +, *, -, ^로 표기하며, 토큰 =는 집합의 상등을 나타낸다.

변수에는 다음 표기로 값을 지정할 수 있다.

<digit>          -> '0' | '1' | ... | '9'
<element>        -> <digit>*
<variable value> -> <var> <ws> '=' <ws> <values>
<values>         -> <element>
                  | <element> <space or tab> <ws> <values>

당신은 한 가지 제한된 종류의 방정식만 풀면 된다. 전체집합을 제외한 모든 변수는 방정식에 정확히 한 번씩만 나타난다. 이러한 방정식과 일부 변수의 값(전체집합은 항상 주어진다)이 주어질 때, 나머지 미정의(undefined) 변수에 Ω\Omega의 부분집합을 지정해 방정식을 성립시킬 수 있는지 판정하고, 가능하다면 그 부분집합들을 출력하라.

입력

첫째 줄에는 풀어야 할 방정식이 주어지며, 길이는 최대 10001000자이다. 전체집합을 제외한 모든 변수는 방정식에 정확히 한 번 나타난다.

이후 각 줄은 한 변수의 값을 정의한다. 전체집합은 리터럴 이름 Omega로 표기되며 그 정의는 항상 존재한다. 각 변수 이름의 길이는 최대 1010자이다. 전체집합의 원소 개수는 최대 500500개이고, 각 원소는 00 이상 500500 이하의 정수이다. 모든 집합은 Ω\Omega의 부분집합이다. 모든 변수 정의의 총 길이는 최대 100 000100\,000자이다.

출력

방정식을 만족시킬 수 있으면 첫째 줄에 Solution을, 그렇지 않으면 No Solution을 출력한다.

해가 존재할 때는 유효한 배정이 여러 개일 수 있으므로 다음의 표준(canonical) 해를 출력한다. Ω\Omega의 각 원소를 독립적으로 처리한다. 한 원소를 고정하고, 각 미정의 변수에 대해 그 원소가 그 변수에 속하는지 여부를 정하는 모든 방법 중에서 이 원소에 대해 방정식을 성립시키는 것만 남긴 뒤, 그중 사전순으로 가장 작은 것을 고른다. 이때 미정의 변수는 이름의 오름차순 ASCII 순서로 나열하고, "속하지 않음"(00)을 "속함"(11)보다 작은 것으로 본다.

첫째 줄 다음에는 이름의 오름차순 ASCII 순서로 각 미정의 변수에 대해 한 줄씩 출력한다. 각 줄은 변수 이름, 공백, =을 쓰고, 그 뒤에 그 변수에 속하는 원소들을 증가하는 수 순서로 각각 공백에 이어 출력한다. 집합이 비어 있는 변수는 이름, 공백, =만 출력한다.

예제6

  1. 예제 1

    입력
    Omega - OneOrThree = Two
    Omega = 1 2 3
    Two = 2
    
    예상 출력
    Solution
    OneOrThree = 1 3
    
  2. 예제 2

    입력
    Omega * result * result = Empty
    Omega = 1 2 3 4 5
    Empty =
    
    예상 출력
    Solution
    result =
    
  3. 예제 3

    입력
    (one+two) ^(TWO+three) = result
    one =1
    TWO =1 3 4 5
    two =2
    three=3
    Omega=1 2 3 4 5
    result = 2 3 4 5
    
    예상 출력
    Solution
    
  4. 예제 4

    입력
    Omega ^Omega = Omega
    Omega=123 234 345 456
    
    예상 출력
    No Solution
    
  5. 예제 5

    입력
    A + B = Omega
    Omega = 1 2
    
    예상 출력
    Solution
    A =
    B = 1 2
    
  6. 예제 6

    입력
    (P + Q) ^ Omega = R
    Omega = 1 2 3
    R = 2
    
    예상 출력
    Solution
    P =
    Q = 1 3