단어로 된 수학 문제를 푸는 숙제를 받은 민식이를 도와주자.
각 알파벳에 대해서 0 ~ 9 사이의 숫자를 대입했을 때 합이 최대는 값을 찾아주자
백트래킹으로 풀기에는 생각보다 간당간당한 문제
처음에는 사용되는 알파벳에 9부터 역순으로 값을 대입해 보는 방법을 사용했지만 결과는 시간초과
TC조차도 상당히 오랜 시간이 걸렸다.
두번째로 선택한 방법은 사용되는 알파벳이 최대 10개이기에 10개에 맞춰 저장을 하고 각 값에 대해서 값을 지정하고
모든 값이 지정이 된다면 값을 치환해 결과를 구하는 방식으로 구했다.
두번째 방법이 되려 첫번째 방법보다 연산이 많아 시간이 오래 걸릴 것 처럼 보였지만 되려 시간이 단축되었다.
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
const int MAX = 10;
int alphaCount;
int n;
int mxm;
vector<char[MAX+1]> words(MAX);
char useAlpha[MAX];
short alphaValue[MAX];
bool check[MAX];
int find(char c)
{
for (int i = 0; i < alphaCount; i++)
if (useAlpha[i] == c)
return i;
return -1;
}
void backTrack(int pos)
{
if (pos == alphaCount)
{
int sum = 0;
/*for (int i = 0; i < alphaCount; i++)
cout << alphaValue[i] << ' ';*/ // For Debug
for (int i = 0; i < n; i++)
{
int cal = 0;
int len = strlen(words[i]);
for (int j = 0; j < len; j++)
cal = (cal * 10) + alphaValue[find(words[i][j])];
sum += cal;
// cout << cal << ' '; // For debug
}
// cout << sum << '\n'; // For debug
if (mxm < sum)
mxm = sum;
}
else
{
for (int i = 0; i < alphaCount; i++)
{
if (check[i])
continue;
alphaValue[pos] = MAX - i - 1;
check[i] = true;
backTrack(pos + 1);
check[i] = false;
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> words[i];
for (int j = 0; words[i][j] != '\0'; j++)
if (find(words[i][j]) == -1)
useAlpha[alphaCount++] = words[i][j];
}
backTrack(0);
cout << mxm;
return 0;
}
2019-02-08 22:30:17에 Tistory에서 작성되었습니다.