《挑战程序设计竞赛》Note_1

2019-04-19  本文已影响0人  Vincy_ivy
时间复杂度:

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是将范围扩大了,防止数组越界。

上一篇 下一篇

猜你喜欢

热点阅读