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

1339 단어 수학

by neohtux 2020. 3. 9.
728x90

 

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

 

1339번: 단어 수학

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

www.acmicpc.net

단어 수학 성공

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

2 초 256 MB 5279 2108 1525 41.239%

문제

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

단어 수학 문제는 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. 문제의 사용 가능한 단어의 갯수  N(1 ≤ N ≤ 10)은 10개로  

총 경우의 수는 10!로 완전탐색으로 1억미만의 연산이 가능함.

 

2.또한 중복된 문자가 있을경우 사용여부를 체크하여 최대값을 만들기 위해  9부터

단어의 갯수만큼 내림차순으로 나열하여 경우의 수를 따져 볼 수 있다.

 

3. 다음순열을 이용하기위해 정렬을 함.

 

4. 알파벳은 총 32개로 check의 범위를 10개의 갯수인줄 10으로 배열을 잡으면

인덱스 오류로 런타임 에러가 발생할 수 있음.

 

5. 순열을 통해 9의 내림차수 숫자로 해당 숫자들을 돌리면서
해당 인덱스가 가리키는 9~0까지 숫자가 몇인지 매칭시켜주면 됨.

 

6.나머지는 대입하여 식 계산.

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

vector<string> str;
int check[30];
vector<int> arr;
vector<int>index;
int get_index(int n,int length);
int times[11] = { 
	1, 
	10, 
	100, 
	1000, 
	10000, 
	100000,
	1000000, 
	10000000, 
	100000000, 
	1000000000,
	1000000000};
int ans;
int main(void)
{
	int N;
	cin >> N;
	
	int length = 0;
	vector<string> op;


	for (int i = 0; i < N; ++i)
	{
		string s;
		cin >> s;
		op.push_back(s);
		for (int k = 0; k < s.size(); ++k)
		{
			if (check[s[k] - 'A'] == false)
			{
				check[s[k] - 'A'] = true;
				index.push_back(s[k] - 'A');
				length++;
			}
				
		}
	}

	
	for (int i = 9; i >= 10 - length; --i)
	{
		arr.push_back(i);
	}
	sort(arr.begin(), arr.end());
	
	int max = 0;
	do
	{

		for (int i = 0; i < N; ++i)
		{
			string str = op[i];

			for (int j = 0; j <= str.length()-1; ++j)
			{
				int a = arr[get_index(str[j] - 'A',length)]; //G C F

				a *= times[str.size()-j-1];
				ans += a;
			}
		}
		if (ans > max) max = ans;
		ans = 0;
	} while (next_permutation(arr.begin(), arr.end()));
	// 
	cout << max << '\n';
	
	return 0;
}
int get_index(int n,int length)
{
	for (int i = 0; i < length; ++i)
	{
		if (n == index[i])
			return i;
	}
}
300x250

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

1018 체스판 다시 칠하기  (0) 2020.03.10
2669 직사각형 네개의 합집합의 면적 구하기  (0) 2020.03.09
1991 트리순회  (0) 2020.03.06
10974 모든 순열  (0) 2020.03.06
7568 덩치  (0) 2020.03.05

댓글