본문 바로가기
Algorithm/완전탐색(BruteForce)

1339 단어 수학(순열 풀이)

by neohtux 2020. 4. 1.
728x90

 

https://www.acmicpc.net/problem/1339

 

1339번: 단어 수학

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대 10개이고, 수의 최대 길이는 8이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.

www.acmicpc.net

단어 수학

시간 제한메모리 제한제출정답맞은 사람정답 비율

2 초 256 MB 5662 2258 1641 41.681%

문제

민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.

단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.

예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다.

N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.

입력

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대 10개이고, 수의 최대 길이는 8이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.

출력

첫째 줄에 주어진 단어의 합의 최댓값을 출력한다.

<풀이>

 

1. 최대 알파벳 단어 10개를 나열하는 가지의 수 10! =< 400만으로

 모든 경우의 수를 따져봐도 많지 않기 때문에 순열을 이용하여 전부 경우의 수를 파악할 수 있다.

 

2. 알파벳 갯수는 26개이다. 어떤 알파벳이 입력으로 들어왔는지 해당 알파벳의 인덱스 값을 

담는 리스트를 만들어 저장

 

3. 가장 큰 값을 찾는것이기 때문, 숫자9부터 단어의 갯수만큼 입력 받는다.

 

4. 단어의 갯수만큼 입력받은 숫자를 오름차순 정렬시킨다음 다음 순열을 검사

 

5. 검사할때마다, 2에서 알파벳 인덱스값과 일치하는 단어가 있으면, 4번의 순열 숫자들을 대입

 

6. 그 연산된 값들의 합의 최대값을 구한다.

 

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;

vector<string> v_str;
bool check[27];
vector<int> arr;
vector<int> arr_index;
void check_alph(vector<string> &str);
void solve();
int N;
int main(void)
{
	cin >> N;
	for (int i = 1; i <= N; ++i)
	{
		string str;
		cin >> str;
		v_str.push_back(str);
	}
	check_alph(v_str);

	for (int i = 0; i < 26; ++i)
	{
		if (check[i]) arr_index.push_back(i);
	}
	int length = 10 - arr_index.size();
	for (int i = 9; i >= length; --i)
	{
		arr.push_back(i);
	}
	sort(arr.begin(), arr.end());
	solve();
	return 0;
}
void check_alph(vector<string> &str)
{
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < str[i].size(); ++j)
		{
			check[str[i][j] - 'A'] = true;
		} 
	}
}
void solve()
{
	int max = 0;
	do
	{
		int ans = 0;
		for (int i = 0; i < N; ++i)
		{
			string s_str = v_str[i];
			int temp = 0;
			for (int k = 0; k < s_str.size(); ++k)
			{
				temp *= 10;
				for (int q = 0; q < arr_index.size(); ++q)
				{
					if (arr_index[q] == s_str[k] - 'A')
					{
						temp += arr[q];
						break;
					}
				}
			}
			ans += temp;
		}
		if (max < ans) max = ans;
		

	} while (next_permutation(arr.begin(), arr.end()));

	cout << max << '\n';
}

 

 

300x250

'Algorithm > 완전탐색(BruteForce)' 카테고리의 다른 글

14889 스타트와 링크 (순열 풀이)  (0) 2020.04.01
14888 연산자 끼워넣기 (순열 풀이)  (0) 2020.04.01
2529 부등호 (순열 풀이)  (0) 2020.03.27
1182 부분수열의 합  (0) 2020.03.13
1436 영화감독 숌  (0) 2020.03.13

댓글