백준: Silver② - 1292, 1312, 1316, 1331

2 분 소요


</br> 계속 풀이
</br>

1292: 쉽게 푸는 문제

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

1 2 2 3 3 3 4 4 4 4 … 같은 수열에서 구간의 합 구하기

방법 1.

    int ia = 0, ib;
    for(int i = 1; i < 1000; i++){
        if( ia == 0 && i*(i+1)/2 >= a ){
            ia = i;
        }
        if( i*(i+1)/2 >= b ){
            ib = i;
            break;
        }
    }
    int ans = 0;
    if( ia == ib ){
        if( a == b ) ans = ia;
        else  ans += (b-a+1) * ia;
        cout << ans << endl;
        return 0;
    }
    ans += ( b - ib*(ib-1)/2 ) * ib;
    ans += ( ia*(ia+1)/2 - a + 1 ) * ia;
    for(int i = ia+1; i < ib; i++){
        ans += i*i;
    }
    cout << ans << endl;

처음에 쓴 코드는 사람처럼 머리 써서 구하는 코드다.
시작점과 끝점에 해당하는 수를 각각 알아내고, 더해주는 코드…

하지만 구현도 귀찮고 복잡하니까, 컴퓨터 답게 푸는 코드를 다시 써 보았다.

방법 2.

    int l = 1;
    for(int i = 1; i <= b; i++){
        for(int j = 0; j < l; j++){
            L[i+j] = l;
        }
        i += l-1;
        l++;
    }
    int ans = 0;
    for(int i = a; i <= b; i++){
        ans += L[i];
    }
    cout << ans << endl;

이건 그냥 수열을 다 구하고, 구간 합을 더해서 구한다. 범위가 1000까지기 때문에 시간도 안 걸린다.
</br>

1312: 소수

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

A를 B로 나누었을 때 소수점 N번째 숫자 구하기

    int ans = 0;
    for(int i = 0; i < n; i++){
        a %= b;
        a *= 10;
        ans = a/b;
    }
    cout << ans << endl;

사람이 하는 나눗셈을 그대로 구현하면 된다.
A를 B로 나누고 나머지를 저장하고, 그걸 10배 해 주고, 몫을 답에 저장하고
</br>

1316: 그룹 단어 체커

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

알파벳이 연속해서 안 나오고 띄엄 띄엄 나오는 지 보기

    int cnt = 0;
    for(int i = 0; i < n; i++){
        string s;
        cin >> s;
        memset(alphabets, 0, 26*sizeof(int));
        s += s[s.size()-1];
        cnt++;
        for(int i = 0; i < s.size()-1; i++){
            if( alphabets[s[i]-'a'] ){
                cnt--;
                break;
            }
            if( s[i] != s[i+1] ){
                alphabets[s[i]-'a'] = 1;
            }
        }
    }
    cout << cnt << endl;

for문에서 만약 현재 문자와 다음 문자가 달라질 때 alphabets[]에 표시해 준다. 그리고 만약 그 문자가 나중에 다시 나온다면 alphabets[]에서 이미 체크되었으므로 cnt-- 해 준다.
</br>

1331: 나이트 투어

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

나이트의 움직임으로 모든 칸을 순회할 수 있는 지 확인하기

    int prevx = s[0] - 'A';
    int prevy = s[1] - '1';
    int startx = prevx;
    int starty = prevy;
    mmap[prevx][prevy] = 1;
    for(int i = 1; i < 36; i++){
        cin >> s;
        int x = s[0] - 'A';
        int y = s[1] - '1';
        bool b = false;
        for(int j = 0; j < 8; j++){
            if( prevx + movex[j] == x && prevy + movey[j] == y ){
                b = true;
                break;
            }
        }
        if( !b ){
            cout << "Invalid" << endl;
            return 0;
        }
        if( mmap[x][y] ){
            cout << "Invalid" << endl;
            return 0;
        }
        mmap[x][y] = 1;
        prevx = x, prevy = y;

    }
    bool b = false;
    for(int j = 0; j < 8; j++){
        if( prevx + movex[j] == startx && prevy + movey[j] == starty ){
            b = true;
            break;
        }
    }
    if( !b ){
        cout << "Invalid" << endl;
        return 0;
    }
    cout << "Valid" << endl;

그냥… 했다 시키는 대로
나이트의 움직임이 맞는 지 확인하고, 이미 방문했는 지도 확인하고, 가장 마지막 방문점이 시작점인 지도 확인한다.
</br>


열심히 하자
</br>

댓글남기기