洛谷题解:P3399 【丝绸之路】
洛谷题解:P2364 【胖男孩】
洛谷题解:P1020 【导弹拦截】
洛谷题解:P1160 【队列安排】
洛谷题解:P1004 【方格取数】
Posted RainyLLL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷题解part相关的知识,希望对你有一定的参考价值。
有 2^n(n≤7)个国家参加世界杯决赛圈且进入淘汰赛环节。已经知道各个国家的能力值,且都不相等。
能力值高的国家和能力值低的国家踢比赛时高者获胜。
1 号国家和 2 号国家踢一场比赛,胜者晋级。
3 号国家和 4 号国家也踢一场,胜者晋级……
晋级后的国家用相同的方法继续完成赛程,直到决出冠军。给出各个国家的能力值,请问亚军是哪个国家?
第一行一个整数 n,表示一共 2^n个国家参赛。
第二行 2^n 个整数,第 i 个整数表示编号为 i 的国家的能力值(1≤i≤2n)。
数据保证不存在平局。
仅一个整数,表示亚军国家的编号。
#include<iostream>
#include<algorithm>//sort
using namespace std;
struct comp
int en;//能力值
int id;//编号
country[130];
bool cmp(comp x,comp y)
return x.en>y.en;//能力值较大的靠前
int n;
int main()
cin>>n;
int cnt=1<<n;//与pow(2,n)等价,适用pow函数需要<cmath>头文件
for(int i=1;i<=cnt;++i)//编号1~cnt
cin>>country[i].en;
country[i].id=i;
sort(country+1,country+cnt/2+1,cmp);//编号 1 ~ cnt/2 排序
sort(country+cnt/2+1,country+cnt+1,cmp);//编号 cnt/2+1 ~ cnt 排序
if(country[1].en<country[cnt/2+1].en)cout<<country[1].id<<endl;//冠亚军决赛取败者
else cout<<country[cnt/2+1].id<<endl;
return 0;
有一个 n(n≤106) 个结点的二叉树。给出每个结点的两个子结点编号(均不超过 n),建立一棵二叉树(根节点的编号为 1)。
如果是叶子结点,则输入 0 0
。
建好这棵二叉树之后,请求出它的深度。二叉树的深度是指从根节点到叶子结点时,最多经过了几层。
第一行一个整数 n,表示结点数。
之后 n 行,第 i 行两个整数 l、r,分别表示结点 i 的左右子结点编号。若 l=0 则表示无左子结点,r=0 同理。
一个整数,表示最大结点深度。
思路:起点为根节点,如果有左子节点就先去它的左子节点,如果该节点若有左子节点则继续深入,
直到节点node无左子节点,之后回退到node的父节点,找node的右子节点Rnode,持续深入直到叶子节点,
若无路可走就持续回退,直到所有的点都被访问过一次,典型的dfs。
7 2 7 3 6 4 5 0 0 0 0 0 0 0 0
4#include<iostream>
#include<algorithm>
using namespace std;
struct node
int lnode,rnode;
;
node tree[1000005];
int n,maxx=0;
void dfs(int start,int deep)
if(start==0)return;//到达叶子则结束
maxx=max(deep,maxx);//更新
dfs(tree[start].lnode,deep+1);//没到叶子的话,就从该节点的左子节点出发继续深入,当前深度+1
dfs(tree[start].rnode,deep+1);//没到叶子的话,就从该节点的右子节点出发继续深入,当前深度+1
int main()
cin>>n;
for(int i=1;i<=n;++i)
cin>>tree[i].lnode>>tree[i].rnode;
dfs(1,1);//初始深度为1,从1号节点出发
cout<<maxx<<endl;
return 0;
输入一串二叉树,输出其前序遍历。
第一行为二叉树的节点数 n。(1≤n≤26)
后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。
空节点用 *
表示
二叉树的前序遍历。
思路:用整数存储节点的左右子节点,用字符存储节点原本名称(最后输出需要)。
根据前序遍历规则(根-左-右),依次输出。
6 abc bdi cj* d** i** j**
abdicj
#include<iostream>
#include<algorithm>
using namespace std;
struct node
char name;
int lnode,rnode;
tree[26*4];
void exp(int x)
cout<<tree[x].name;
if(tree[x].lnode)exp(tree[x].lnode);//如果有左子节点就往下探索
if(tree[x].rnode)exp(tree[x].rnode);//如果有右子节点就往下探索
//前序遍历顺序为根节点——左子树——右子树
int n;
char r,s,t,root,rl,rr;
int main()
cin>>n;
cin>>root>>rl>>rr;
int start=root-\'a\'+1;
tree[start].name=root;
if(rl!=\'*\')tree[start].lnode=rl-\'a\'+1,tree[rl-\'a\'+1].name=rl;
if(rr!=\'*\')tree[start].rnode=rr-\'a\'+1,tree[rr-\'a\'+1].name=rr;//根节点设置
for(int i=2;i<=n;++i)
cin>>r>>s>>t;
tree[r-\'a\'+1].name=r;
if(s!=\'*\')tree[r-\'a\'+1].lnode=s-\'a\'+1,tree[s-\'a\'+1].name=s;
if(t!=\'*\')tree[r-\'a\'+1].rnode=t-\'a\'+1,tree[t-\'a\'+1].name=t;
exp(start);
return 0;
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,且二叉树的节点个数 ≤8)。
共两行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
共一行一个字符串,表示一棵二叉树的先序。
思路:按照样例:根据后序排列规则,最后一个被访问的节点为根节点,所以A为根节点,然后再从中序排列中找到A,这时中序排列中可分为B和DC两棵子树,对应的从后序排列中可以找到B和DC。
那么现在变成 中序排列为B,后序排列为B;中序排列为DC,后序排列为DC。
所以整个过程是不断找子根并输出,然后根据子根将子树拆分成两部分。
BADC BDCA
#include<iostream>
#include<cstring>
using namespace std;
char zhong[10],hou[10];
int find(char x)
int flag=-1;
for(int i=0;i<strlen(zhong);++i)
if(x==zhong[i])flag=i;
return flag;
void xian(int lz,int rz,int lh,int rh)//分别表示中序排列左右下标区间和后序排列左右下标区间
int k=find(hou[rh]);//找根节点位置
cout<<hou[rh];
if(k>lz)xian(lz,k-1,lh,rh-(rz-k+1));//k-lz,左子节点数,rz-k+1,右子节点数
if(k<rz)xian(k+1,rz,lh+k-lz,rh-1);
int main()
cin>>zhong;
cin>>hou;
int len=strlen(hou);
xian(0,len-1,0,len-1);
return 0;
以上是关于洛谷题解part的主要内容,如果未能解决你的问题,请参考以下文章