1 条题解

  • 0
    @ 2025-8-24 21:44:38

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar winmt
    **

    搬运于2025-08-24 21:44:38,当前版本为作者最后更新于2016-10-09 21:52:50,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我又来发第一个题解辣~【以下代码省略头文件】

    本题要考虑相对位置而不是绝对位置。。。其实很容易想到:如果5张照片中有大于或等于3张照片里牛A在牛B的前面,那么开始序列中牛A一定在牛B之前。这样我们就很容易得到了下面的代码:

    int n;
    int p,ans[20005];
    map<int,int>r[10];
    bool cmp(int x,int y)
    {
        int f=0;
        for(int i=1;i<=5;i++)
        {
            if(r[i][x]<r[i][y])f++;
        }
        return f>=3;
    }
    int main()
    {
        cin>>n;
        for(int k=1;k<=5;k++)
        {
            for(int i=1;i<=n;i++)
            {
                cin>>p;
                ans[i]=p;
                r[k][p]=i;
            }
        }
        sort(ans+1,ans+n+1,cmp);
        for(int i=1;i<=n;i++)cout<<ans[i]<<endl; 
        return 0;
    }
    

    这个代码在USACO官网提交是AC的,USACO标程也差不多这样,但是在洛谷上只能拿80分,TLE后两个大数据,这是为什么呢?我也在这里卡了很久,不知其为啥TLE。(插叙:于是我傻逼的与kkk争论了起来,kkk说是STL-sort常数大,说改成手写版就AC了~这是有道理的,但是我有更好的办法,只需改一点点2333,最终还比kkk总共快500ms左右,想知道的继续看下去!)其实这段代码本身就是超时的,USACO开了O2所以能过。你可能会说这程序sort是nlogn,所以复杂度就是O(nlogn),可以过啊~但是别忘了map是很慢的,map速度是logn,其中n是节点个数。我们可以精确计算下上面代码的时间复杂度:5*nlogn*2*logn=10*n*(logn)^2,n取200000,所以算一下就知道大约是578000000,这还只是算了sort的cmp函数里的复杂度啊就早爆了!所以立马就得到用map不行,那么秒想到用哈希啊!(注意要解决哈希冲突)很容易得到了以下代码:

    int n;
    int p,ans[20005];
    vector<pair<int,int> >r[10][9975];
    bool cmp(int x,int y)
    {
        int f=0;
        for(int i=1;i<=5;i++)
        {
            int num1=0,num2=0;
            int kkk1=x%9973,kkk2=y%9973;
            for(int j=0;j<r[i][kkk1].size();j++)
            {
                if(r[i][kkk1][j].first==x)num1=r[i][kkk1][j].second;
            }
            for(int j=0;j<r[i][kkk2].size();j++)
            {
                if(r[i][kkk2][j].first==y)num2=r[i][kkk2][j].second;
            }
            if(num1<num2)f++;
        }
        return f>=3;
    }
    int main()
    {
        cin>>n;
        for(int k=1;k<=5;k++)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&p);
                ans[i]=p;
                r[k][p%9973].push_back(make_pair(p,i));
            }
        }
        sort(ans+1,ans+n+1,cmp);
        for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
        return 0;
    }
    

    虽然长了一些,但相比kkk的方法修改幅度小很多。我们再算下时间复杂度:忽略常数是5*nlogn,n取200000,算出来得:17000000,显然之虽然仅是STL-sort的cmp函数内时间复杂度,但是就算加上其他的复杂度也不会有问题嘚~所以这题就轻松搞定啦!23333 这也告诉我们C++党:不能依赖STL,特别是map之类狂慢的。。。也一定要算算时间复杂度,不能盲目地觉得AC就提交了~

    • 1

    信息

    ID
    2098
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者