《挑战程序设计竞赛》例题:抽签(升级篇)

题目大意见第一篇文章,区别是n的范围由【1,50】变成了【1,1000】
分析:因为n范围变大了,而四重循环的时间复杂度为o(图片说明 )将1000带入显然不行,会超时,考虑一下第四重循环的数可以有关系式得出k=m-a[i]-a[x]-a[y],所以只要验证k是不是数组a中的一员就行了,这里我们采用二分法,二分法的时间复杂度是o(logn)所以总的时间复杂度是o( 图片说明 logn)(将1000带入也超过图片说明 )所以还要简化算法,这里我们将前两个循环合成一个循环,将前两个循环移出去,用一个数组装下他们所有的和也就是n*n个数,所以就有关系式:b数组中的某个数=m-a[i]-a[x],这下就只用两个循环了,时间复杂度大大降低
源代码如下:

三重循环的源码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;//n为口袋中纸的数目,m是要求的和,ki为某张纸上的数字
    cin>>n>>m;
    int a[n];//数组a为储存纸上数字的数组
    for(int i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        for(int x=0;x<n;x++)
        {
            for(int y=0;y<n;y++)
            {
                if(binary_search(a,a+n,m-a[i]-a[x]-a[y]))//binary_search是c++ STL中的,进行二分查找模板binary_search(arr[],arr[]+n,x)arr[]为数组首地址,n为数组大小,x为想查找的数
                {
                    cout<<"yes"<<endl;//这里记得用b数组噢
                    return 0;//保证只输出一个yes,否则后面也可能出现符合的组合
                }

            }
        }
    }
    cout<<"no"<<endl;
}
二重循环的源码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;//n为口袋中纸的数目,m是要求的和,ki为某张纸上的数字
    cin>>n>>m;
    int a[n],b[n*n];//数组a为储存纸上数字的数组
    for(int i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        for(int x=0;x<n;x++)
        {
            b[i*n+x]=a[i]+a[x];
        }
    }
    sort(b,b+n*n);
    for(int i=0;i<n;i++)
    {
        for(int x=0;x<n;x++)
        {
                if(binary_search(b,b+n*n,m-a[i]-a[x]))//binary_search是c++ STL中的,进行二分查找模板binary_search(arr[],arr[]+n,x)arr[]为数组首地址,n为数组大小,x为想查找的数
                {
                    cout<<"yes"<<endl;
                    return 0;//保证只输出一个yes,否则后面也可能出现符合的组合
                }

        }
    }
    cout<<"no"<<endl;
}

全部评论

相关推荐

比亚迪汽车新技术研究院 硬件工程师 总包21左右 硕士
点赞 评论 收藏
分享
牛客263158796号:我领羊一面后十天不挂也不推进 今天问hr说等前序的第一批意向发完看情况再看是否推进
点赞 评论 收藏
分享
安静的垂耳兔在泡澡:ks已经第八次投递了,它起码挂了还让你再投,不错了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务