SWEA 알고리즘

1244. [S/W 문제해결 응용] 2일차 - 최대 상금

kangyuseok 2023. 5. 11. 21:22
728x90

문제

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

다음과 같이 입력이 주어질 경우 {123 1} 123을 1번 자리를 교환해 가장 큰 수를 만들어야 한다.

예시에서는 1과 3을 바꿔 321이 정답이다.

{94 2} 일 경우 94 -> 49 -> 94 이다.

처음에는 단순히 백트래킹 기법으로 모든 자리를 교환해 그 중 가장 큰 수를 출력할려 했다.

sol(st, change); //입력 받은 String 숫자배열, change는 교환할 수 있는 수

void sol(string s, int cnt)
{
    if (cnt == 0) //cnt가 0이면 다 교환했다는 의미 이므로 최댓값을 갱신
    {
        int temp = stoi(s);
        ans = max(ans, temp);
        return;
    }

    for (int i = 0; i < s.length() - 1; i++) //백트래킹 부분
    {
        for (int j = i + 1; j < s.length(); j++)
        {
            swap(s[i], s[j]);
            sol(s, cnt - 1);
            swap(s[i], s[j]);
        }
    }
}

위의 경우에는 시간초과가 나오게 된다....

따라서 중복되는 수는 체크를 해줘야한다.

예를 들어 {333 1} 로 주어지면 333, 333, 333이 세번 나오게 되는데 중복체크를 안해주면 시간이 걸린다.

chk[a][b]가 true이며는 b번 교환했을 때, a라는 값은 이미 나온 값이다.

void sol(string s, int cnt)
{
    if (cnt == 0)
    {
        int temp = stoi(s);
        ans = max(ans, temp);
        return;
    }

    for (int i = 0; i < s.length() - 1; i++)
    {
        for (int j = i + 1; j < s.length(); j++)
        {
            swap(s[i], s[j]);
            int Temp = stoi(s);
            if (chk[Temp][cnt-1] == false)
            {
                chk[Temp][cnt-1] = true;
                sol(s, cnt - 1);
            }
            swap(s[i], s[j]);
        }
    }
}

전체 코드이다.

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <math.h>
#include <cstring>
using namespace std;
int ans;
bool chk[1000000][11];
int num = 1;
void sol(string s, int cnt);
int change;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        string st;
        cin >> st;

        cin >> change;

        sol(st, change);

        cout << '#' << num << ' ' << ans << '\n';
        ans = 0;
        memset(chk, false, sizeof(chk));
        num++;
    }
    return 0;
}
void sol(string s, int cnt)
{
    if (cnt == 0)
    {
        int temp = stoi(s);
        ans = max(ans, temp);
        return;
    }

    for (int i = 0; i < s.length() - 1; i++)
    {
        for (int j = i + 1; j < s.length(); j++)
        {
            swap(s[i], s[j]);
            int Temp = stoi(s);
            if (chk[Temp][cnt-1] == false)
            {
                chk[Temp][cnt-1] = true;
                sol(s, cnt - 1);
            }
            swap(s[i], s[j]);
        }
    }
}

더 좋은 풀이법도 있다 (시간이 더 빠름)

https://yabmoons.tistory.com/307