본문 바로가기

PS/boj

백준 15811 복면산?!

http://www.acmicpc.net/problem/15811 

 

15811번: 복면산?!

복면산이란 수학 퍼즐의 일종으로, 어떤 계산식의 각 숫자들을 특정 문자로 바꾸면 각 문자가 어떤 숫자인지 맞추는 퍼즐이다. 대표적으로 SEND+MORE=MONEY가 있다. SEND + MORE ------ MONEY S=9, E=5, N=6, D=7,

www.acmicpc.net

브루트포스를 통해 푸는 문제였습니다.

알파벳과 숫자는 1대1 매칭이므로 알파벳-숫자쌍은 최대 10개임을 알 수 있습니다. 따라서 등장알파벳 또한 최대 10개이어야합니다. 10개를 넘을경우 숫자와 매칭할수 없으므로 복면산이 성립될수없습니다. 

O(등장알파벳=최대10!)이르므로 브루트포스를 통해 구할수있습니다. 복면상 성립여부는 최대 18자리이므로  long long A+B 와 long long C를 비교하여 풀었습니다.

#include <stdio.h>
#include<queue>
#include<iostream>
#include<stack>
#include<vector>
#include<set>
using namespace std;
void fast_io() {
  cin.tie(0)->sync_with_stdio(0);
}
string A,B,C;
int chk[130];//ctoi
bool chk2[10];
bool solve;
int al,bl,cl,sl;
set<char> s;
vector<char> vec;
string rev(string a){
    string ret;
    stack<char> stk;
    for(auto i : a) stk.push(i);
    while(!stk.empty()){
        ret+=stk.top();
        stk.pop();
    }
    return ret;
}
void bf(int now){
    if(now==sl){
        int k=0;
        long long temp=0;
        long long temp2=0;
        long long digit=1;
        long long digit2=1;
        for(int x=0;x<max(al,bl);x++){
            int nowa=0;
            int nowb=0;
            int nowc=0;
            if(x<al){
                nowa=chk[A[x]];
            }
            if(x<bl){
                nowb=chk[B[x]];
            }
            temp+=(long long)((nowa+nowb+k)%10)*digit;
            k=(nowa+nowb+k)/10;
            digit*=10LL;
        }
        if(k){
            temp+=k*digit;
        }
        for(auto i : C){
            temp2+=(long long)chk[i]*digit2;
            digit2*=10LL;
        }
        if(temp!=temp2) return;
        solve=true;
        return;
    }
    for(int x=0;x<10;x++){
        if(chk2[x]) continue;
        chk[vec[now]]=x;
        chk2[x]=true;
        bf(now+1);
        chk2[x]=false;
    }
}
int main() {
    fast_io();
    cin>>A>>B>>C;
    A=rev(A);
    B=rev(B);
    C=rev(C);
    al=(int)A.size();
    bl=(int)B.size();
    cl=(int)C.size();
    for(auto i : A) s.insert(i);
    for(auto i : B) s.insert(i);
    for(auto i : C) s.insert(i);
    sl=(int)s.size();
    if(sl>10){
        cout<<"NO";
        return 0;
    }
    for(auto i : s){
        vec.push_back(i);
    }
    bf(0);
    if(solve){
        cout<<"YES";
    }
    else cout<<"NO";
}