백준: Silver4② - 1063, 1065, 1120

3 분 소요


</br> 실버 4 문제들 끝~ 강제 갱신하기가 있는 줄 몰랐는데 했더니 점수가 더 올라가서 실버 3이 되었다!
</br>

1063: 킹

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

체스판에 킹과 돌이 있다. 킹은 한 칸 씩 움직이고, 돌을 밀 수 있지만 밖으로 나가게 된다면 움직이지 않는다.

    tuple<int, int> king, stone;
    king = make_tuple(s1[0] - 'A', 8 - s1[1] + '0');
    stone = make_tuple(s2[0] - 'A', 8 - s2[1] + '0');

    for(int i = 0; i < n; i++){
        string s;
        cin >> s;
        int cmd1 = 0, cmd2 = 0;
        if( s == "R" ){
            cmd1 = 1;
        }
        if( s == "L" ){
            cmd1 = -1;
        }
        if( s == "T" ){
            cmd2 = -1;
        }
        if( s == "B" ){
            cmd2 = 1;
        }
        if( s == "RT" ){
            cmd1 = 1;
            cmd2 = -1;
        }
        if( s == "LT" ){
            cmd1 = -1;
            cmd2 = -1;
        }
        if( s == "RB" ){
            cmd1 = 1;
            cmd2 = 1;
        }
        if( s == "LB" ){
            cmd1 = -1;
            cmd2 = 1;
        }
        if( get<0>(king) + cmd1 != 8 && get<0>(king) + cmd1 != -1
                && get<1>(king) + cmd2 != 8 && get<1>(king) + cmd2 != -1 ){
            get<0>(king) = get<0>(king) + cmd1; get<1>(king) = get<1>(king) + cmd2;

            if( get<0>(king) == get<0>(stone) && get<1>(king) == get<1>(stone) ){
                if( get<0>(stone) + cmd1 != 8 && get<0>(stone) + cmd1 != -1
                        && get<1>(stone) + cmd2 != 8 && get<1>(stone) + cmd2 != -1 ){
                    get<0>(stone) = get<0>(stone) + cmd1; get<1>(stone) = get<1>(stone) + cmd2;
                }
                else{
                    get<0>(king) = get<0>(king) - cmd1; get<1>(king) = get<1>(king) - cmd2;
                }
            }
        }
    }
    s1[0] = get<0>(king) + 'A';
    s1[1] = 8 - get<1>(king) + '0';
    s2[0] = get<0>(stone) + 'A';
    s2[1] = 8 - get<1>(stone) + '0';
    cout << s1 << endl;
    cout << s2 << endl;

킹 받는 문제다…
많이 뻘짓했다

여기서 거의 대부분 속았을 반례:

  1. R, L, B, T일 때 그 방향만 체크하면 안 되고 돌과 킹의 위치가 아예 같을 때 돌을 움직여 줘야 함
  2. 돌이 킹한테 밀렸을 때 돌이 체스판 밖으로 나갈 수도 있음(그럼 움직이면 안 됨)

코드는 그냥 그대로 구현한 거…
상황에 맞게 커맨드 설정하고 위 두 규칙을 신경 쓰면 됨.
</br>

1065: 한수

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

한수라는 말은 처음 듣는데 아무튼 등차수열을 붙여서 만들어지는 수? ex) 123, 2468

    int cnt = 0;
    if( n < 100 ) cnt = n;
    else{
        cnt = 99;
        for(int i = 111; i < n+1; i++){
            int k = i;
            bool isHan = true;
            int a, b, c;
            a = k % 10;
            c = k % 10 - (k / 10) % 10;
            a = (k / 10) % 10;
            k /= 100;
            while( k != 0 ){
                b = k % 10;
                if(a - b != c ){
                    isHan = false;
                    break;
                }
                a = b;
                k /= 10;
            }
            if( isHan ){
                cnt++;
            }
        }
    }

    cout << cnt << endl;

백준 예제에서 거의 다 가르쳐 준다.

한 자리 수나 두 자리 수는 무조건 다 한수다. ex) 3, 55, 39

99 다음으로 한수는 111이 있으므로 거기부터 체크한다. 처음에 앞에서부터 떼면서 확인하려 했는데 좀 잘 안 됐는데, 생각해보니까 뒤에서부터 떼도 아무 상관없다. oooba와 같이 a와 b를 구해서 그 둘의 차 c를 구하고, 나머지도 계속 c와 같은 지 확인해 준다.


</br>

1120: 문자열

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

문자열 A와 B가 있는데(길이 A < B), A의 앞뒤에 알파벳을 추가해서 가장 차이가 적게 하기.

    int gap = s2.size() - s1.size();

    int minGap = 51;
    for(int i = 0; i < gap+1; i++){
        int cnt = 0;
        for(int j = 0; j < s1.size(); j++){
            if( s1[j] != s2[j+i] ) cnt++;
        }
        minGap = min(minGap, cnt);
    }
    cout << minGap << endl;

A의 앞뒤만 추가 가능하다는 조건을 안 보고 갑자기 왤케 어려워 졌지?! 했다… local sequence alignment인 줄 알았다

그게 아니고 엄청 간단하다. 문자열 s2와 s1의 길이 차를 구해서, 앞에서부터 그냥 갭을 주면서 차가 제일 적은 걸 구하면 된다. ex) abc-aaaaa => oabc-aaaaa => ooabc-aaaaa
</br>


킹받는 문제 빼고는 괜찮았다…

1
점수가 444네ㅋㅋ
다음은 실버 3
</br>

댓글남기기