1. 程式人生 > 實用技巧 >配置檔案初始化異常Configuration system failed to initialize

配置檔案初始化異常Configuration system failed to initialize

目錄

Codeforces Round #655 (Div. 2)

1. 題目分析

  • A: 思維題,構造性題目
  • B: 打表發現規律
  • C: 思維
  • D: 思維+dp
  • E:
  • F:

2. 題解

A. Omkar and Completion

題意: 給定t個測試樣例,每個測試樣例給定一個n,要求構造一個長度為n的數列,數列中任意兩個數字相加不會等於數列中其他的數字。t~1e3, n~1e3
題解:

本題是構造性的題目,沒說數列中的數字要滿足什麼條件,如果全為1即可
程式碼:

#include <bits/stdc++.h>

using namespace std;

int main() {
    int T, n;
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 1; i  <= n; ++i) {
            cout << 1 << " ";
        }
        cout << endl;
    }
    return 0;
}

B. Omkar and Last Class of Math

題意: 給定一個n,可以把n拆解成a、b,使得a+b=n,求使得lcm(a, b)最小的a和b。n~1e9
題解: 打表發現,如果n是偶數,那麼直接輸出n/2 n/2;如果n是奇數,那麼去找n的最大奇數因數a,輸出a n-a
程式碼

#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
    int T;
    cin >> T;
    for (int i = 1, a; i <= T; ++i) {
        scanf("%d", &a);
        if (a % 2 == 0) {
            cout << a / 2 << " " << a / 2 << endl;
        }
        else {
            int maxv = 1;
            for (int i = 2; i <= a / i; ++i) {
                if (i % 2 == 0) continue;
                if (a % i == 0 && (i > maxv || a / i > maxv)) {
                    if (i > maxv) maxv = max(maxv, i);
                    if (a / i > maxv) maxv = max(maxv, a / i);
                }
            }
            cout << maxv << " " << a - maxv << endl;
        }
    }
    return 0;
}

C. Rational Ratio

題意: 定義一種交換:選擇一段區間[l, r], 一次交換把[l, r]上的所有數改變位置(每個數字都必須改變位置),問把一個任意數列變成有序數列(a[i]=i),需要多少次這樣的交換。數列個數2e5,a[i]~1e18
題解: 分析可知交換隻有0,1,2三種情況,如果一開始就是有序的,輸出0;一開始無序的段只有1個(無序的段意思是這個段內每個數字a[i] != i),那麼輸出1;否則輸出2(如果無序的段有多個,可以把所有無序的段加上中間有序的看作一整個無序的段,然後通過1次交換,使得每個數字都不在原來的位置上,在進行一次交換都回到自己的位置上即可)
程式碼:

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
int const N = 2e5 + 10;
LL a[N];
int T, n;
 
int main() {
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
        int sorted = 1, rand_cnt = 0, contient = 1;
        for (int i = 1; i <= n; ++i) {
            if (a[i] != i) {
                sorted = 0;
                if (contient) {
                    rand_cnt ++;
                    contient = 0;
                }
            }
            if (a[i] == i) {
                contient = 1;
            }
        }
        if (sorted) {
            cout << 0 << endl;
            continue;
        }
        else if (rand_cnt == 1) {
            cout << 1<< endl;
            continue;
        }
        else cout << 2<< endl;
    }
    return 0;
}

D. Omkar and Circle

題意: 給定n個數字,這n個數字都在一個圓上,每次可以選擇3個數字,刪掉這3個數字,把左右兩邊的數字的和賦值給中間的數字。最後圓上只會剩下一個數字,求剩下的數字的最大值。
題解: 選擇3個數字,刪掉這3個數字,把左右兩邊的數字賦值給中間的數字,這樣的操作對於最後的答案來說,就是刪掉中間那個數字。則n個數字,需要刪掉n/2個數字,剩下n/2+1個數字。可以證明被刪掉的數字一定是間隔的,因為如果不是間隔的,一定可以證明為間隔刪更小。既然刪掉n/2個數組,同時是間隔的,那麼剩下的數字有兩個數字是相鄰的,其他都是間隔的。可以選擇去列舉這兩個相鄰的數字,使用dp即可。li[i]維護從i往前,間隔的數字字首和;re[i]維護從i往後,間隔的數字字尾和。不斷列舉li[i]+re[i]的和最大值即可。
程式碼

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
int const N = 2e5 + 10;
LL le[N], ri[N];
int n, a[N];
 
int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    if (n == 1) {
        cout << a[1] << endl;
        return 0;
    }
    for (int i = 1; i <= n; ++i) {
        if (i >= 2) le[i] = le[i - 2] + a[i];
        else le[i] = a[i];
    }
    for (int i = n; i >= 1; --i) {
        if (i <= n - 1) ri[i] = ri[i + 2] + a[i];
        else ri[i] = a[i];
    }
    LL res = -1;
    for (int i = 1; i <= n - 1; ++i) {
        res = max(res, le[i] + ri[i + 1]);
    }
    res = max(res, le[n]);
    cout << res << endl;
    return 0;
}

E. Omkar and Last Floor

F. Omkar and Modes