1. 程式人生 > >USACO 2.2 Runaround Numbers

USACO 2.2 Runaround Numbers

        這又是我想吐槽難度差的一道題……也有可能是我想得太簡單了……

        大致上就是暴力窮舉,每個數字檢查兩個條件:

          1. 每位數字是否不重複

          2. 能否滿足runround的條件,也就是從第1位開始,向後移該位數字的位數,如果迴圈一圈之後發現每位數字都經過了,那麼就滿足條件

        其中,唯一的關鍵點是檢查runround。我的做法是,完全根據題意的邏輯順序來,每次從第一位開始,依次向下移位,直到迴圈到了已經經過的位數,最後統一檢查是否每個數字都經過了。

        以下是程式碼:

#include <iostream>
#include <fstream>
using namespace std;

const int MAXD = 10;
int num[MAXD];
int nLen;
int M;

bool isRunround()
{
    int checks[MAXD] = {0};
    int i;

    i = nLen - 1;
    i = i - num[i] > 0 ? (i - num[i]) % nLen : nLen + (i - num[i]) % nLen;
    while (checks[i] == 0) {
        checks[i] = 1;
        i = i - num[i] > 0 ? (i - num[i]) % nLen : nLen + (i - num[i]) % nLen;
    }

    for (i = 0; i < nLen; i ++)
        if (checks[i] == 0)
            return false;

    return true;
}

bool isUnique()
{
    int checks[MAXD] = {0};
    int i;

    for (i = 0; i < nLen; i ++) {
        if (checks[num[i]] == 1 || num[i] == 0)
            return false;
        checks[num[i]] = 1;
    }
    return true;
}

void getNum(int n)
{
    int i, m;
    for (i = 0, m = n; m != 0; i ++, m /= 10)
        num[i] = m % 10;
    nLen = i;
}

int main()
{
    ifstream fin ("runround.in");
    ofstream fout ("runround.out");
    int i;

    fin >> M;
    for (i = M+1; ; i ++) {
        getNum(i);
        if (isUnique() && isRunround())
            break;
    }
    fout << i << endl;
}

        閒話時間,我發現,暴力窮舉什麼的我真是越做越順手了_(:з」∠)_