zoukankan      html  css  js  c++  java
  • Noip模拟考试7:解题报告

    1 . 二叉树
    ( ( binary .cpp/c/pas)
    【问题描述】
    二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
    (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    (3)左、右子树也分别为二叉排序树;
    (4)没有键值相等的结点。
    完全二叉树:只有最下面的两层结点度能够小于2,并且最下面一层的结点
    都集中在该层最左边的若干位置的二叉树。

    给出N个数,且这N个数构成1至N的排列。现在需要你按顺序构建一棵二叉
    排序树,并按照层次遍历的方式输出它,然后判断它是否是一棵完全二叉树。

    【输入格式】
    输入文件名为binary.in。
    输入文件包含两行。第一行为一个正整数N;第二行为1至N的排列。
    【输出格式】
    输出文件名为binary.out。
    输出文件包含两行。第一行为构建出的二叉排序树的层次遍历;第二行判
    断是否是完全二叉树:若是输出yes,否则输出no。

    解题:二叉树实现建树。观察可知若maxo>n则输出no

    maxo=n则输入yes

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxm 1100010
    #define maxn 25
    using namespace std;
    int n,b,dep,deep,flag,Jud,maxo;
    int tree[maxm],a[maxn];
    void build(int o,int now)
    {
        if(!tree[o])
        {
            tree[o]=now;
            maxo=max(maxo,o);
            return ;
        }
        if(now<tree[o])build(o<<1,now);
        else build(o<<1|1,now);
        return ;
    }
    int main()
    {
    //    freopen("binary.in","r",stdin);
    //    freopen("binary.out","w",stdout);
        scanf("%d",&n);
        for(int i = 1 ; i <= n ; ++i)
            scanf("%d",&a[i]);
        tree[1]=a[1];
        for(int i = 2 ; i <= n ; ++i)
            build(1,a[i]);
        for(int i = 1 ; i<=maxo; ++i)
            {
                if(!tree[i])continue;
                printf("%d ",tree[i]);
            }
        if(maxo>n)printf("
    no");
        else printf("
    yes");
        return 0;
    }

    2 2 . 列车调度
    (manage.cpp/c/pas)
    【问题描述】
    有N辆列车,标记为1,2,3,…,N。它们按照一定的次序进站,站台共有K个轨
    道,轨道遵从 先进先出的原则。列车进入站台内的轨道后可以等待任意时间后出
    站,且所有列车不可后退。现在要使出站的顺序变为N,N-1,N-2,…,1,询问K的
    最小值是多少。
    例如上图中进站的顺序为1,3,2,4,8,6,9,5,7,则出站的顺序变为
    9,8,7,6,5,4,3,2,1。
    【输入格式】
    输入文件名为manage.in。
    输入共2行。
    第 1 行包含1个正整数N,表示N辆列车。
    第 2 行包含N个正整数,为1至N的一个排列,表示进站次序。
    【输出格式】
    输出文件名为manage.out。
    输出共1行,包含1个整数,表示站台内轨道数K的最小值。

    由于每次寻找轨道中大于当前序号的最小序号,所以用二分查找实现。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int ans,top,n,a[200005],q[200005];
    int main()
    {
    //    freopen("manage.in","r",stdin);
    //    freopen("manage.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int l,r;
        top=1;
        q[1]=a[1];
        for(int i=2;i<=n;i++){
            if(a[i]>q[top])
            {
                q[++top]=a[i];
                continue;
            }
            l=0;r=top;
            while(r-l>1){
                int m=(l+r)>>1;
                if(q[m]<a[i])l=m;
                else r=m;
            }
            q[r]=a[i];
        }
        printf("%d",top);
        return 0;
    }

    3. 保留道路
    (road .cpp/c/pas)
    【问题描述】
    很久很久以前有一个国家,这个国家有N个城市,城市由1,2,3,…,N标号,
    城市间有M条双向道路,每条道路都有两个属性g和s,两个城市间可能有多条道
    路,并且可能存在将某一城市与其自身连接起来的道路。后来由于战争的原因,
    国王不得不下令减小花费从而关闭一些道路,但是必须要保证任意两个城市相互
    可达。
    道路花费的计算公式为wG*max{所有剩下道路的属性g}+wS*max{所有剩下道
    路的属性s},其中wG和wS是给定的值。国王想要在满足连通性的前提下使这个花
    费最小,现在需要你计算出这个花费。
    【输入格式】
    输入文件名为road.in。
    第一行包含两个正整数N和M。
    第二行包含两个正整数wG和wS。
    后面的M行每行描述一条道路,包含四个正整数u,v,g,s,分别表示道路连接
    的两个城市以及道路的两个属性。
    【输出格式】
    输出文件名为road.out。
    输出一个整数,表示最小花费。若无论如何不能满足连通性,输出-1。

    解题:

    初步考虑kruskal,由于影响因素有两个,所以我们对g 进行sort,再维护s。

    每一次加边的时候,我们先将加入边存入一个维护s从小到大的数组中,然后进行kruskal,再判断边数是否=n-1,若等于n-1则更新答案。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 50010
    #define maxm 410
    #define inf 1ll<<60
    #define ll long long
    using namespace std;
    int num,top;
    ll ans=inf;
    int fa[maxm],st[maxm],n,m;
    ll wg,ws;
    struct edge{
        int u,v,g,s;
    }a[maxn];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    bool cmp(edge x,edge y){return x.g<y.g;}
    int main()
    {
    //    freopen("road.in","r",stdin);
    //    freopen("road.out","w",stdout);
        scanf("%d%d",&n,&m);
        scanf("%I64d%I64d",&wg,&ws);
        for(int i = 1 ; i <= m ; ++i)
            scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].g ,&a[i].s );
        sort(a+1,a+1+m,cmp);
        top=0;
        for(int i = 1 ; i <= m ; ++i)
        {
            int j;
            for( j = 1 ; j <= n ; ++j)
                fa[j]=j;
            for( j = top ; j >= 1 ; --j)
            {
                if(a[st[j]].s >a[i].s)
                    st[j+1]=st[j];
                else break;
            }
            top++;st[j+1]=i;
            num=0;
            for(int j = 1 ; j <= top ; ++j)
            {
                int fx=find(a[st[j]].u );
                int fy=find(a[st[j]].v );
                if(fx!=fy)
                {
                    fa[fx]=fy;
                    st[++num]=st[j];
                }
            }
            if(num==n-1)
                ans=min(ans,wg*a[i].g+ws*a[st[num]].s);
            top=num;
        }
        if(ans==inf)printf("-1");
        else printf("%I64d",ans);
        return 0;
    }
  • 相关阅读:
    UDK Stat命令
    绝地求生-全军出击手游
    UE3中的时间
    Git原理与命令大全
    【SpringCloud】Spring Cloud Alibaba 之 Nacos注册中心(二十七)
    【SpringCloud】Spring Cloud Alibaba 及 Nacos介绍(二十六)
    【Web】Keepalived+Nginx 实现高可用集群
    【SpringCloud】Spring Cloud Sleuth + Zipkin + RabbitMQ 集成(二十五)
    【SpringCloud】Spring Cloud Sleuth 日志跟踪(二十六)
    Spring框架学习笔记(5)——Spring Boot创建与使用
  • 原文地址:https://www.cnblogs.com/fujudge/p/7397311.html
Copyright © 2011-2022 走看看