zoukankan      html  css  js  c++  java
  • 清北第二套题

                                            

    【问题描述】

    栈是一种强大的数据结构,它的一种特殊功能是对数组进行排序。例如,借助一个栈,依次将数组1,3,2按顺序入栈或出栈,可对其从大到小排序:

    1入栈;3入栈;3出栈;2入栈;2出栈;1出栈。

    在上面这个例子中,出栈序列是3,2,1,因此实现了对数组的排序。

    遗憾的是,有些时候,仅仅借助一个栈,不能实现对数组的完全排序。例如给定数组2,1,3,借助一个栈,能获得的字典序最大的出栈序列是3,1,2:

    2入栈;1入栈;3入栈;3出栈;1出栈;2出栈。

    请你借助一个栈,对一个给定的数组按照出栈顺序进行从大到小排序。当无法完全排序时,请输出字典序最大的出栈序列。

    【输入格式】

    输入共行。

    第一行包含一个整数,表示入栈序列长度。

    第二行包含个整数,表示入栈序列。输入数据保证给定的序列是到n的全排列,即不会出现重复数字。

    【输出格式】

    仅一行,共个整数,表示你计算出的出栈序列。

    【样例输入】

    3

    2 1 3

    【样例输出】

    3 1 2

    【样例解释】

    这回山里有座塔。

    【数据规模与约定】

    对于30%的数据,1<=N<=10^3。

    对于60%的数据,1<=N<=10^5。

    对于100%的数据,1<=N<=10^6。

     

     

    题解:感觉自己的代码有种超时的即视感,然而并没有。先找最大的,前面的都入栈。然后找第二大,如果在栈顶,出栈,如果没有,比较栈顶元素和maxn(没入栈的元素)谁大,如果栈顶元素大,出栈,反之将在maxn之前的元素全部入栈,继续重复前面操作。直到栈空。

     

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define N 1000100
    using namespace std;
    int n,top(0),maxn;
    int a[N],zh[N];
    bool f[N]={0};
    void xx()
    {
        while (f[maxn]) maxn--;
        while (zh[top]>maxn&&top) 
          { 
               printf("%d ",zh[top]);
               top--;
               while (f[maxn]) maxn--;
          }
    }
    int main()
    {
       freopen("haha.in","r",stdin);
       freopen("haha.out","w",stdout);
       scanf("%d",&n);
       for (int i=1;i<=n;i++) scanf("%d",&a[i]);
       maxn=n;
       for (int i=1;i<=n;i++)
         {
             if (a[i]!=maxn) zh[++top]=a[i],f[a[i]]=1;
             if (a[i]==maxn) 
               {
                    f[maxn]=1;
                  printf("%d ",a[i]);
                 xx();
              }  
         }
        while (top) 
          {
               printf("%d ",a[top]);
               top--;
          }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

                                                               

    【问题描述】

    小Q对计算几何有着浓厚的兴趣。他经常对着平面直角坐标系发呆,思考一些有趣的问题。今天,他想到了一个十分有意思的题目:

    首先,小Q会在轴正半轴和轴正半轴分别挑选个点。随后,他将轴的点与轴的点一一连接,形成条线段,并保证任意两条线段不相交。小Q确定这种连接方式有且仅有一种。最后,小Q会给出个询问。对于每个询问,将会给定一个点,请回答线段OP与条线段会产生多少个交点?

    小Q找到了正在钻研数据结构的你,希望你可以帮他解决这道难题。

    【输入格式】

    第行包含一个正整数,表示线段的数量;

    第行包含个正整数,表示小Q在轴选取的点的横坐标;

    第行包含个正整数,表示小Q在轴选取的点的纵坐标;

    第4行包含一个正整数,表示询问数量;

    随后行,每行包含两个正整数,表示询问中给定的点的横、纵坐标。

    【输出格式】

    共行,每行包含一个非负整数,表示你对这条询问给出的答案。

    【样例输入】

    3

    4 5 3

    3 5 4

    2

    1 1

    3 3

    【样例输出】

    0

    3

    【样例解释】

    然后塔里啥都没有。

    【数据规模与约定】

    对于50%的数据,1<=n,m<=2*10^3。

    对于100%的数据,1<=n,m<=2*10^5,坐标范围<=10^8。

      

    题解:由于n条线段互不相交,因此将x和y从小到大排序,一一对应形成线段。二分答案,若此时点P与原点形成的线段与此时的第mid条线段相交,则一定与在mid之前的线段相交。判断是否相交时,可以将P点的横坐标第mid条直线的解析式中求出y来,将y与P点的纵坐标进行比较,若y比P点的纵坐标大,说明两线段相交,反之则不相交。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 200100
    #define ll long long
    using namespace std;
    int n,m,ans;
    double x[N],y[N];
    bool check(int k,double x1,double y1)
    {
        if (k==0) return 0;
        double Y=-y[k]/x[k]*x1+y[k];//求把此时的横坐标代入第k条线段对应的纵坐标 
        return Y<y1;
    }
    int main()
    {
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
        
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%lf",&x[i]);
        for (int i=1;i<=n;i++) scanf("%lf",&y[i]);
        sort(x+1,x+n+1);//小的x对应小的y,保证线段不相交 
        sort(y+1,y+n+1);
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
          {
                double xx,yy;
                scanf("%lf%lf",&xx,&yy);
                 int l=0,r=n;
                while (l<=r)
                  {
                     int mid=(l+r)>>1;
                     if (check(mid,xx,yy)) ans=mid,l=mid+1;
                       else r=mid-1;
                }
             cout<<ans<<endl;
          } 
        fclose(stdin);
        fclose(stdout);
        
        return 0;
    }
    lsj大神

     

  • 相关阅读:
    start pyhton project(2)
    java.lang.ClassFormatError: Truncated class file
    linux 查看计算机信息命令
    VS2010UltimTrialCHS 版注册码
    VS2008打包安装程序,实现覆盖安装设置
    WPF移动不规则渐变色窗体
    C#下移动无边框窗体(直接粘贴可用)
    TCP通信过程中时时监测连接是否已断开
    WIN7下使用DotNetBar,关闭Aero效果,使用Office2007Form皮肤
    【原创】企业级工作流管理系统评价依据或标准
  • 原文地址:https://www.cnblogs.com/sjymj/p/6039540.html
Copyright © 2011-2022 走看看