백준: Gold4 - 1261, 1339

1 분 소요


</br> 계속 계속
</br>

1261: 알고스팟

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

(1,1)에서 (n,m)까지 벽을 몇 번 부숴야 하는지

    queue<P> q;
    q.push(mp(0, 0));
    dp[0][0] = 0;
    int d = 0, ans = 0;
    while( q.size() ){
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            if( nx < 0 || n <= nx || ny < 0 || m <= ny ) continue;
            if( dp[nx][ny] > dp[x][y] + mmap[nx][ny] ){
                dp[nx][ny] = dp[x][y] + mmap[nx][ny];
                q.push(mp(nx, ny));
            }
        }
    }

    cout << dp[n-1][m-1] << endl;

처음엔 dp로 풀면 되나? 했는데, 그냥 순차적으로 증가한다고 되는 게 아니더라.
그래서 bfs로 접근하면서, `dp[x][y] = min(dp[x][y], 이전 dp값 + 0 또는 1)로 업데이트 해 주었다.
현재 지도에서 0일 경우 부술 필요 없으므로 0을 더하고, 1일 경우 벽이므로 1을 더한다. 그 값이 현재 dp의 값보다 작다면 더 좋은 경로이므로 업데이트한다.
</br>

1339: 단어 수학

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

각 알파벳을 임의의 숫자로 치환했을 때 단어들의 합이 최대가 되기를 구하기

처음에는 그리디로, 자리수가 큰 순으로 정렬 후 알파벳마다 숫자를 배정했는데, 그렇게 풀면 반례가 있더라.

ex)
10
ABB
BB
BB
BB
BB
BB
BB
BB
BB
BB

내가 생각한 알고리즘 대로면 A=9, B=8이 되어야 하지만, BB는 10번 나오고 A00은 한 번 나오므로 B=9, A=8을 해야 합이 더 크게 나온다.

    for(int i = 0; i < n; i++){
        string s;
        cin >> s;
        for(int j = 0; j < s.size(); j++){
            nums[s[j] - 'A'] += pow(10, s.size()-j-1);
        }
    }
    sort(nums, nums + 26, greater<>());
    int num = 9;
    int ans = 0;
    for(int i = 0; i < 26; i++){
        ans += nums[i] * num;
        num--;
    }
    cout << ans << endl;

따라서 다시 생각한 게, 일단 알파벳을 다 1이라 생각하고 그 합들을 알파벳마다 저장한다.

ex) ABC, DDDD, AD
-> A: 100 + 10 = 110
   B: 10
   c: 1
   D: 1111 + 1 = 1112

따라서 이 합대로 정렬해서, 차례대로 큰 숫자를 주면 큰 숫자와 합이 큰 게 곱해지므로 해결 된다.
</br>


https://ideone.com/ 직접 인풋 넣고 돌려볼 수 있는 사이트가 있더라 좋다
로컬에서는 시간 측정이 정확하지 않을 수 있어서
</br>

댓글남기기