美文网首页
《挑战程序设计竞赛》Note_1

《挑战程序设计竞赛》Note_1

作者: Vincy_ivy | 来源:发表于2019-04-19 22:47 被阅读0次
时间复杂度:

1000000 游刃有余
10000000 勉勉强强
100000000 很悬,仅限循环体非常简单的情况
二分查找复杂度是O(logn),即使n变得很大时,对数时间的算法依然非常迅速
排序O(nlogn)
循环O(n^3logn)

复杂抽签问题:1.1

首先呢,是最初始的状态:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m,kk[51*51],k[51];
int main()
{
    freopen("data.in.txt","r",stdin);
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>k[i];
    for(int a=0;a<n;a++)
                for(int b=0;b<n;b++)
                          for(int b=0;b<n;b++)
                                  for(int b=0;b<n;b++)
                                            if(k[a]+k[b]+k[c]+k[d]==m)
                                                     f=true;
        if(f)
                cout<<"YES";
        else
                cout<<"NO";
    return 0;
}

然后将最后一个条件换了
如果你真的去用四个for,机器比你还先爆,所以才要改写,不过这思路在做c语言作业时,家长就和我说过,只不过我当时没有想到可以用到acm上。就是将内侧的循环替换成二分搜索算法,时间复杂度就变成
排序O(nlogn)时间
循环O(n^3logn)时间
合起来就是O(n^3logn)时间

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m,k[51];
bool binary_search(int x){
    int l=0,r=n;
    while(r-l){
        int i=(l+r)/2;
        if(x==k[i]) return true;
        else if(x<k[i]) l=i+1;
        else    r=i;
    }
    return false;
}

int main()
{
    freopen("data.in.txt","r",stdin);
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>k[i];
    bool f=false;
    sort(k,k+n);
    for(int a=0;a<n;a++)
        for(int b=0;b<n;b++)
            for(int c=0;c<n;c++){
                if(binary_search(m-k[a]-k[b]-k[c]))
                    f=true;
            }   
    if(f)
        cout<<"YES";
    else
        cout<<"NO";
    return 0;
}

O(n^2logn)算法

今天还学到了一个新的办法:
排序:O(n^2logn) 这里排了两次序
循环:O(n^2logn)

    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    int n,m,kk[51*51],k[51];
    bool binary_search(int x){
        int l=0,r=n*n;
        while(r-l){
            int i=(l+r)/2;
            if(x==kk[i])        return true;
            else if(x>kk[i])    l=i+1;
            else    r=i;
        }
        return false;
    }

    void solve(){
        for(int c=0;c<n;c++)
            for(int d=0;d<n;d++)
                kk[c*n+d]=k[c]+k[d];
        sort(kk,kk+n*n);
        bool f=false;
        for(int a=0;a<n;a++)
            for(int b=0;b<n;b++)
                if(binary_search(m-k[a]-k[b]))
                    f=true;
        if(f)
            cout<<"YES";
        else
            cout<<"NO";
    }

    int main()
    {
        freopen("data.in.txt","r",stdin);
        cin>>n>>m;
        for(int i=0;i<n;i++)
            cin>>k[i];
        bool f=false;
        sort(k,k+n);
        solve();
            return 0;
    }

其实这里面用了n*n是将范围扩大了,防止数组越界。

相关文章

  • 《挑战程序设计竞赛》Note_1

    时间复杂度: 1000000 游刃有余10000000 勉勉强强100000000 ...

  • 用快速幂运算求斐波那契,时间复杂度降到O(logn)

    思路来自《挑战程序设计竞赛》 可运行的C++代码如下

  • 简介

    这是关于《挑战程序设计竞赛(第2版)》的刷题记录。因为POJ评测快,全英文,评测结果反馈与ICPC竞赛相同,所以选...

  • 挑战程序设计竞赛11.7

    今天读的挑战程序设计竞赛的图的最短路问题,只看了一个dijkstra算法,但没怎么看明白。 又把昨天的bellma...

  • 挑战程序设计竞赛11.4

    /* 今天读了一种叫做并查集的数据结构,以前做题做到了,但一些解题报告质量参差不齐, 自己只是理解个大概了,不知道...

  • 挑战程序设计竞赛11.2

    今天读了如何实现优先队列,及如何运用。可以用数组来表示二叉树,节点是从上到下从左到右的顺序紧凑排列,它最重要的性质...

  • 挑战程序设计竞赛11.3

    今天读了二叉搜索树的实现以及set和map的简单用法。 二叉搜索树实际上就是一颗二叉树,但它有一个特点,就是每个节...

  • 挑战程序设计竞赛11.11

    今天在高铁上读了一点,只看了辗转相除法。 int gcd(int a,int b){ if(b==0) retur...

  • 挑战程序设计竞赛11.5

    今天读了挑战程序设计竞赛的2.5,介绍了图的一些概念。 图的表示方法,邻接矩阵和邻接表。 邻接矩阵可以简单地建一个...

  • 多重集组合数

    在挑战程序设计竞赛第69页公式dp[i+1][j] = dp[i][j] + dp[i+1][j-1] - dp[...

网友评论

      本文标题:《挑战程序设计竞赛》Note_1

      本文链接:https://www.haomeiwen.com/subject/eugtgqtx.html