맑은 신의 시뮬레이션 | 반복(중복 제외), 쿼리 + DFS

5435 단어

1019 | 천자백태


정아팔경은 카타란으로 세어야 한다고 한다.거위
  • 가능한 두 갈래 나무 형태수 = 가능한 두 갈래 수색 나무 형태수 어떤 두 갈래 나무든 중순으로 훑어보는 순서에 따라 결점에 값을 부여하면 두 갈래 수색 나무를 형성할 수 있다
  • 한 그루, n개의 결점, 좌우자수 결점은 모두 nn-1개이다.왼쪽 0 오른쪽 nn-1, 왼쪽 1 오른쪽 nn-2,..., 왼쪽 nn-1 오른쪽 0으로 뜯을 수 있습니다.누적: 왼쪽*오른쪽은 곱하기 모드를 주의하고, 더하기 모드를 주의합니다..
  • 결과를 저장하고 계산을 반복하지 않도록 주의하세요..
  • 초기: 결점수 0, 형태 1종;결점수 1, 형태 1종..
  • 카타란수 추이h(n) = h(n-1)*(4n-2)/(n+1) 모형을 찾을 수 없습니다. 왜냐하면(4n-2)/(n+1) 소수일 수도 있어요.다른 공식을 사용할 수 있습니다: (n+1)!(2n)!/n!
  • #include 
    #include 
    
    #define MOD 1000000007
    using namespace std;
    typedef long long LL;
    LL type_cnt[1001] = {0};
    
    LL dfs(int num) {
        if (num == 1 || num == 0) return type_cnt[num];
        for (int i = 0; i < num; ++i) {
            if (type_cnt[i] == 0) type_cnt[i] = dfs(i);
            if (type_cnt[num - i - 1] == 0) type_cnt[num - i - 1] = dfs(num - i - 1);
            type_cnt[num] = (type_cnt[num] + type_cnt[i] * type_cnt[num - i - 1] % MOD) % MOD;
        }
        return type_cnt[num];
    }
    
    int main() {
        int ign, n;
        scanf("%d%d", &ign, &n);
        type_cnt[0] = 1, type_cnt[1] = 1;
        printf("%lld
    ", dfs(n)); return 0; }

    1023 | 누락수


    PAT에서 잃어버린 최소 정수를 찾는 것처럼 쓴 다음에 TLE.문제 풀이를 보았다.
  • 우선, n개수에서 부족한 최소 정수는 n+1보다 클 수 없다.정수 정렬을 기록하면, n+1보다 큰 숫자는 기억하지 않아도 된다
  • 표준 해법은 모든 수를 자신의 위치로 돌아가 i에서 n까지 반복하게 한다. 만약arr[arr[i]에 존재하는 것이arr[i]가 아니라면 순환하고 swap한다.⚠️순환, 아래 표시는 경계를 넘지 마라
  • #include 
    #include 
    
    using namespace std;
    int vec[10000001];
    
    int main() {
        int nn;
        long long temp;
        scanf("%d", &nn);
        for (int i = 1; i <= nn; ++i) {
            scanf("%lld", &temp);
            vec[i] = int(temp);
        }
        for (int i = 1; i <= nn; ++i) {
            while (vec[i] <= nn && vec[i] > 0 && vec[vec[i]] != vec[i])
                swap(vec[i], vec[vec[i]]);
        }
        for (int i = 1; i <= nn; ++i) {
            if (vec[i] != i) {
                printf("%d
    ", i); return 0; } } printf("%d
    ", nn + 1); return 0; }

    1024 | 우주 트리


    좀 종합적이야.
  • 여러 개의 연결 분량이 있을 수 있습니다 (모서리를 입력할 때 사용하고 집합을 검사합니다. 기호가 큰 것은 기호가 작은 것으로 합쳐집니다)
  • 각 집합의 맏형부터 DFS, 유지보수 경로의 값을 주의하세요..
  • DFS의 return 조건
    .45, 6, 7, 917. 자기가 맏형..
  • 아이가 없어요.한 모서리만 있고 다른 세그먼트는 이 경로에 있습니다(방문한 적이 있습니다. 아버지입니다..

  • 경로값의 덧셈은 대정수 덧셈을 사용해야 한다(갑작스러워...)
  • 대정수 덧셈 길이는 둘 중 하나를 취하고 부족하면 0을 보충하고 마지막 진위를 주의하세요..
  • 전도 0의 처리에 주의하고 전도 0을 제거한 후 공백으로 다시 0을 보충합니다
  • reverse 계산 잘 하시고..

  • DFS 시 경로 유지 보수visited true/false,push_back/pop_back 짝짓기..
  • #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    int nn, mm, uf[10001];
    string path_val, tree_val;
    char types[10001];
    vector graph[10001];
    bool visited[10001] = {false};
    
    int _find(int a) {
        return uf[a] < 0 ? a : uf[a] = _find(uf[a]);
    }
    
    void _union(int a, int b) {
        a = _find(a);
        b = _find(b);
        if (a != b) {
            int ta = min(a, b), tb = max(a, b);
            uf[ta] += uf[tb];
            uf[tb] = ta;
        }
    }
    
    string str_plus(string &sa, string &sb) {
        int la = sa.length(), lb = sb.length();
        int extra = 0, temp;
        string res;
        int i = la - 1, j = lb - 1;
        for (; i >= 0 || j >= 0; i--, j--) {
            int a = i >= 0 ? sa[i] - '0' : 0, b = j >= 0 ? sb[j] - '0' : 0;
            temp = extra + a + b;
            extra = temp / 10;
            temp %= 10;
            res += char(temp + '0');
        }
        if (extra) res += char(extra + '0');
        while (res.back() == '0') res.pop_back();
        if (res.empty()) res = "0";
        reverse(res.begin(), res.end());
        return res;
    }
    
    void DFS(int curr) {
        if (graph[curr].empty()) {
            string temp;
            temp += types[curr];
            tree_val = str_plus(tree_val, temp);
            return;
        }
        if (graph[curr].size() == 1 && visited[graph[curr][0]]) { // leaf
            path_val += types[curr];
            tree_val = str_plus(tree_val, path_val);
            path_val.pop_back();
            return;
        }
        visited[curr] = true;
        path_val += types[curr];
        for (auto item:graph[curr]) {
            if (!visited[item])DFS(item);
        }
        visited[curr] = false;
        path_val.pop_back();
    }
    
    int main() {
        scanf("%d%d
    ", &nn, &mm); fill(uf, uf + nn, -1); int v1, v2; for (int i = 0; i < nn; ++i) scanf("%c ", &types[i]); for (int i = 0; i < mm; ++i) { scanf("%d%d", &v1, &v2); graph[v1].push_back(v2); graph[v2].push_back(v1); _union(v1, v2); } vector roots; int cnt = 0; for (int i = 0; i < nn; ++i) { _find(i); if (uf[i] < 0) { roots.push_back(i); cnt++; } } printf("%d
    ", cnt); for (int i = 0; i < cnt; i++) { tree_val = "0"; DFS(roots[i]); printf("%s", tree_val.data()); printf(i + 1 == cnt ? "
    " : " "); fill(visited, visited + nn, false); } return 0; }

    좋은 웹페이지 즐겨찾기