竞争性编程的黄金法则 - 练习题(1)

算法和计算复杂度(问题A01-A05/B01-B04)

总结

题单(问题A01-A05/B01-B04)

主要是简单题,但是很多题都是可以以更优的时间复杂度通过的

A05 - Three Cards

本题 $O(n^2)$ 即可通过(甚至$O(n^3)$也可以卡过),这里我们用一种$O(n)$的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void solve()
{
    int n,k;
    cin>>n>>k;
    ll ans=0;
    for(int i=1;i<=n;i++){
        int rest = k - i;
        if (rest < 2) break;
        int min_val = max(1LL, rest - n);
        int max_val = min(n, rest - 1);
        if (min_val <= max_val) {
            ans += max_val - min_val + 1;
        }
    }
    cout<<ans<<endl;
}

事实上可以$O(1)$,但是代码过于繁琐,详见

B03 - Supermarket 1

本题$O(n^3)$ 可通过,这里用了$O(n^2)$ 的做法,但是额外消耗了$O(n^2)$ 的空间

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
unordered_set<int> sum[2010];

void solve()
{
    int n;cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    vector<int> ex(2010);
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            ex[a[i]+a[j]]++;
            sum[a[i]+a[j]].insert(i);
            sum[a[i]+a[j]].insert(j);
        }
    }
    for(int i=0;i<n;i++){
        //保证a[i]不在已经被选的两个中
        if(ex[1000-a[i]]>0&&sum[1000-a[i]].find(i)==sum[1000-a[i]].end()){
            cout<<"Yes\n";
            return ;
        }
    }
    cout<<"No\n";
}
Licensed under CC BY-NC-SA 4.0
最后更新于 Jan 24, 2024 00:00 UTC
本博客已稳定运行
使用 Hugo 构建
主题 StackJimmy 设计