1. 程式人生 > 其它 >acwing周賽50

acwing周賽50

題目連結

1.缺少的數

模擬 \(O(n)\)

可以使用桶排序,將未出現的字母輸出即可

時間複雜度

遍歷一次O(n)

C++程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5 +  10;
int n;
int num[N];
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int a;
        cin >> a;
        num[a] = 1;
    }
    for(int i = 1; i <= n; i++)
    {
        if(!num[i])
        {
            cout << i;
            return 0;
        }
    }
    return 0;
}

2.4417. 選區間

演算法(排序+模擬) \(O(nlogn)\)

題目大意是讓我們找出最小可能值的最大值多少,如果區間存在交集那麼距離為0,如果無交集,那麼距離為l2-r1,找出這樣距離的最大值。
我們可以將區間進行排序,分別遍歷一類區間與二類區間,每次與另外一個區間區域的最後一個區間進行比較即可,因為無法確定是哪一個區間更大,所以遍歷兩次。

時間複雜度

排序時間複雜度為\(O(nlogn)\), 遍歷為\(n\),所以總和為\(O(n)\)

C++程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int n, m;
vector<PII> ll, rr;
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        ll.push_back({a, b});
    }
    cin >> m;
    for(int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        rr.push_back({a, b});
    }
    sort(ll.begin(), ll.end());
    sort(rr.begin(), rr.end());
    int res = 0;

    for(int i = 0; i < n; i++)
    {
        auto c = ll[i];
        auto d = rr[m - 1];
        res = max(res, d.first - c.second);
    }
    for(int i = 0; i < m; i++)
    {
        auto c = rr[i];
        auto d = ll[n - 1];
        res = max(res, d.first - c.second);
    }
    cout << res;
    return 0;
}

3.選元素

動態規劃

閆式dp分析法

狀態表示:從前i個數選擇j個數的集合,並且選擇了第i個數的集合
狀態計算:對於選擇的第i個元素,那麼我們j與j - 1的距離不應該大於k,也就可以得出i-k <= u < i
得出 dp[i][j] = max(dp[i][j], dp[u][j - 1] + v) (i - k u i)

時間複雜度

i*j*u,為\(O(n^3)\)

C++程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210;
typedef long long LL;
int n, k, x;
LL dp[N][N];  

int main()
{
    memset(dp, -0x3f, sizeof dp);   //清空
    cin >> n >> k >> x;
    dp[0][0] = 0;   //初始化為0
    for(int i = 1; i <= n; i++)
    {
        int v;
        cin >> v;
        for(int j = 1; j <= x; j++)
            for(int u = max(0, i - k); u < i; u++)  //也許會小於0,所以與0做判斷
                dp[i][j] = max(dp[i][j], dp[u][j - 1] + v);
    }
    
    LL ans = -1;
    for(int i = n - k + 1; i <= n; i++)
        ans = max(ans, dp[i][x]);
    cout << ans;
    return 0;
}