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("\nno");
    else printf("\nyes");
    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;
}
时间: 2024-10-22 14:00:30

Noip模拟考试7:解题报告的相关文章

暑假第四次考试 冲刺Noip模拟赛4 解题报告——五十岚芒果酱

题1 韬韬抢苹果(apple) [问题描述] 又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹 果.每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了一项 特殊的规则,按体重的大小来定顺序,每一轮都是先由胖的先摘(照顾胖子),每个韬韬都 是很聪明的,不会错过眼前最大的苹果.现在问题来了,一共有 n 个苹果,m 个韬韬,要你 按原顺序输出每个韬韬可以抢到的苹果的总大小. [输入格式]apple.in 第一行两个数 n,m. 接下来一行 n 个数,分

CH Round #54 - Streaming #5 (NOIP模拟赛Day1)解题报告

最近参加了很多CH上的比赛呢~Rating--了..题目各种跪烂.各种膜拜大神OTZZZ T1珠 描述 萌蛋有n颗珠子,每一颗珠子都写有一个数字.萌蛋把它们用线串成了环.我们称一个数字串是有趣的,当且仅当它的第1位是2,且除了第1位以外的每一位都是3.例如,2,233,2333333都是有趣的数字串.现在,你可以从这串珠子的任意一颗开始读,沿着顺时针或逆时针方向,到任意一颗珠子停止.这样,你就可以读出一个数字串来.萌蛋想知道,所有能读出的有趣的数字串当中,最长的是哪一个数字串.当然,你也可能读不

CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告

T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7=3,3×5 mod 7=1.如果继续乘下去,就会陷入循环当中.萌蛋还发现,这个循环的长度经常会是φ(n),即小于n且与n互质的正整数的个数.例如,φ(7)=6,而上述循环的长度也是6,因为5,4,6,2,3,1共有6个数.再如n=6,那么5×5 mod 6=1.这个循环的长度很短,只有2,而恰好φ

20161022 NOIP模拟赛 T2 解题报告

旅行者问题 [问题描述] lahub是一个旅行者的粉丝,他想成为一个真正的旅行者,所以他计划开始一段旅行.lahub想去参观n个目的地(都在一条直道上).lahub在起点开始他的旅行.第i个目的地和起点的距离为ai千米(ai为非负整数).不存在两个目的地和起点的距离相同. 从第i个目的地走到第j个目的地所走的路程为 |ai-aj|千米.我们把参观n个目的地的顺序称作一次“旅行”.lahub可以参观他想要参观的任意顺序,但是每个目的地有且只能被参观一次(参观顺序为n的排列). lahub把所有可能

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的

Noip模拟考试6:解题报告

Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数数组.Peter求出了这个数组的所有子段和,并将这n(n+1)/2个数降序排序,他想知道前k个数是什么. 不难想到,从最大字段和向下更新. 用set实现 介绍一下set:用法与priority_queue基本相同,区别是,set有自动去重,而priority_queue将所有元素放入. 然后通过三元组,分别记录权值,左端与右端. #include<cstdio> #include<algorithm>

Noip模拟考试八:解题报告

1. 鼎纹(grain.cpp/.c/.pas)[问题描述]据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗练成历史的遗存.聪明的古代劳动人民拥有一个 a 行 b 列的铜模,每个位置要么是 0(代表这个点是平的),要么是 1(代表这个点是凸起的).他们想造 个 n 行 m 列的鼎 ,其中每个位置也都是 0 或 1,表示经过若干 次印后,每个位置的结果.有一些要求.铜模是不能旋转和翻转的:在印的过程当中,铜模的凸起不能出现在

冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱

1.ksum(ksum) [问题描述] Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数 数组. Peter求出了这个数组的所有子段和,并将这n(n+1)/2个数降序排序,他想 知道前k个数是什么. [输入格式] 输入文件名为 ksum.in. 输入数据的第一行包含两个整数 n 和 k. 接下来一行包含 n 个正整数,代表数组. [输出格式] 输出文件名为 ksum.out. 输出 k 个数,代表降序之后的前 k 个数,用空格隔开. [输入输出样例] ksum.i

【一个蒟蒻的挣扎】模拟赛2解题报告

---恢复内容开始--- 今天50分,我自闭 眼瞎看错了一道题,然后两道题的代码都出了点小毛病,自闭 真的竞赛我要这样可以收拾收拾退役了真的,眼睛不能这么瞎了考试莫得人帮忙改了 如果一切都没问题今天应该有130,啊!!!!!!!!!!!!!!!!! 今天两题可以用堆,一题模拟随便写写就过了,(所以我为什么考这么差) 进入正题 题目一览(其实就3道题)(CZR到底是谁这么爱数学和折磨我们) 24点 小游戏 中位数 题1. 24点 题目描述 1.1 Background CZR很喜欢学数学,但是他数