团体天梯练习 L2-026 小字辈
Posted MAKISE004
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了团体天梯练习 L2-026 小字辈相关的知识,希望对你有一定的参考价值。
L2-026 小字辈
本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。
输入格式:
输入在第一行给出家族人口总数 \\(N\\)(不超过 \\(100 000\\) 的正整数) —— 简单起见,我们把家族成员从 \\(1\\) 到 \\(N\\) 编号。随后第二行给出 \\(N\\) 个编号,其中第 \\(i\\) 个编号对应第 \\(i\\) 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 \\(-1\\) 。一行中的数字间以空格分隔。
输出格式:
首先输出最小的辈分(老祖宗的辈分为 \\(1\\) ,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。
输入样例:
9
2 6 5 5 -1 5 6 4 7
输出样例:
4
1 9
解题思路
题目大致意思就是求出树上层次最大的一层的所有节点,然后对这些节点按照编号排个序输出。方法很明显是 \\(BFS\\) ,只需要记录最后一层的节点即可。
/* 一切都是命运石之门的选择 El Psy Kongroo */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, int> psi;
typedef __int128 int128;
#define PI acos(-1.0)
#define x first
#define y second
//int dx[4] = 1, -1, 0, 0;
//int dy[4] = 0, 0, 1, -1;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 1e5 + 10;
int h[N], e[N], ne[N], idx;
vector<int> res;
int n, root, level;
void add(int a, int b)
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
void bfs()
queue<int> q;
q.push(root);
while(!q.empty())
res.clear();
int nn = q.size();
while(nn -- )
int u = q.front();
q.pop();
res.push_back(u); //记录当前层的节点
for(int i = h[u]; i != -1; i = ne[i])
int v = e[i];
q.push(v);
level ++ ;
//最后结束循环时,res中存储的就是最后一层的所有节点
int main()
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
memset(h, -1, sizeof(h));
cin >> n;
for(int i = 1; i <= n; i ++ )
int fa; cin >> fa;
if(fa != -1) add(fa, i);
else root = i;
bfs();
cout << level << endl;
sort(res.begin(), res.end());
for(int i = 0; i < (int)res.size() - 1; i ++ ) cout << res[i] << \' \';
cout << res.back();
return 0;
一切都是命运石之门的选择,本文章来源于博客园,作者:Amαdeus,出处:https://www.cnblogs.com/MAKISE004/p/17331848.html,未经允许严禁转载
团体程序设计天梯赛-练习集
L2-001 紧急救援 (25 分)
知识点:最短路dij
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\\n",x,y);
typedef long long ll;
using namespace std;
inline int read()
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')w=-1;ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
const int INF=0x3f3f3f;
const int maxn=1000;
int a[maxn];
int edge[maxn][maxn];
int n,m,s,d;
int dis[maxn];
int vis[maxn];
int cnt[maxn];
int num_a[maxn];//最短路上的最大救援队
int pathnum[maxn];//最短路的数量
int path[maxn];
void dij()
pathnum[s]=1;
dis[s]=0;
vis[s]=1;
num_a[s]=a[s];
for(int i=0;i<n;i++)
dis[i]=edge[s][i];
if(edge[s][i]<=INF&&i!=s)
path[i]=s;
num_a[i]=num_a[s]+a[i];
pathnum[i]=1;
for(int i=1;i<n;i++)
int now=0;
int minn=INF;
for(int j=0;j<n;j++)
if(vis[j]==0&&dis[j]<minn)
now=j;
minn=dis[j];
vis[now]=1;
for(int j=0;j<n;j++)
if(!vis[j])
if(dis[j]==edge[now][j]+minn)
pathnum[j]+=pathnum[now];
if(num_a[j]<num_a[now]+a[j])
num_a[j]=num_a[now]+a[j];
path[j]=now;
else if(dis[j]>edge[now][j]+minn)
dis[j]=edge[now][j]+minn;
num_a[j]=num_a[now]+a[j];
pathnum[j]=pathnum[now];
path[j]=now;
void print(int now)
if(now==s)
return ;
print(path[now]);
cout<<" "<<now;
int main()
// memset(edge,0x3f3f3f,sizeof(edge));
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)
dis[i]=INF;
for(int j=0;j<n;j++)
edge[i][j]=edge[j][i]=INF;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=1;i<=m;i++)
int u,v,w;
cin>>u>>v>>w;
edge[u][v]=w;
edge[v][u]=w;
dij();
cout<<pathnum[d]<<" "<<num_a[d]<<endl;
cout<<s;
print(d);
L2-002 链表去重 (25 分)
知识点:模拟链表
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\\n",x,y);
typedef long long ll;
using namespace std;
inline int read()
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')w=-1;ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
const int maxn=2e5+9;
struct node
int add;
int val,next;
link[maxn],b[maxn];
int vis[maxn];
int tot=0;
int main()
int beg,n;
cin>>beg>>n;
for(int i=1;i<=n;i++)
int add,val,nex;
cin>>add>>val>>nex;
link[add].val=val;
link[add].next=nex;
int now=beg;
// printf("----\\n");
while(1)
// printf("now=%d\\n",now);
if(now==-1)
break;
if(vis[abs(link[now].val)]==0)
if(now!=beg)
printf("%05d\\n",now);
vis[abs(link[now].val)]=1;
printf("%05d %d ",now,link[now].val);
// cout<<now<<" "<<link[now].val<<" "<<link[now].next<<endl;
now=link[now].next;
else
b[++tot].next=link[now].next;
b[tot].add=now;
b[tot].val=link[now].val;
now=link[now].next;
printf("-1\\n");
if(tot)
printf("%05d %d ",b[1].add,b[1].val);
for(int i=2;i<=tot;i++)
printf("%05d\\n%05d %d ",b[i].add,b[i].add,b[i].val);
printf("-1\\n");
L2-003 月饼 (25 分)
知识点:贪心
注意要将种类数和需求数都开成double,不然会被卡一个点
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\\n",x,y);
typedef long long ll;
using namespace std;
inline int read()
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')w=-1;ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
const int maxn=2000;
//int num[maxn];
//int val[maxn];
struct node
double num,val;
double ave;
a[maxn];
bool cmp(node a,node b)
return a.val*b.num>b.val*a.num;
int main()
int n,d;
cin>>n>>d;
for(int i=1;i<=n;i++)cin>>a[i].num;
for(int i=1;i<=n;i++)cin>>a[i].val;
for(int i=1;i<=n;i++)a[i].ave=1.0*a[i].val/a[i].num;
sort(a+1,a+1+n,cmp);
double sum=0;
for(int i=1;i<=n;i++)
// cout<<a[i].ave<<endl;
if(d>=a[i].num)
d-=a[i].num;
sum+=a[i].val;
else
sum+=d*a[i].ave;
break;
printf("%.2f\\n",sum);
L2-004 这是二叉搜索树吗? (25 分)
知识点:考察了前序遍历和后序遍历的应用
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\\n",x,y);
typedef long long ll;
using namespace std;
inline int read()
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')w=-1;ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
const int maxn=2000;
int pos[maxn];
int iff=0;
vector<int>post;
void getpos(int l,int r)
if(l>r)return ;
int tl=l+1,tr=r;
if(!iff)//正常的二叉搜索树
while(tl<=r&&pos[tl]<pos[l])tl++;//找到第一个大的
while(tr>l&&pos[tr]>=pos[l])tr--; //找到第一个小的
else //镜像的
while(tl<=r&&pos[tl]>=pos[l])tl++;
while(tr>l&&pos[tr]<pos[l])tr--;
if(tl!=tr+1)return ;
getpos(l+1,tr);
getpos(tl,r);
// cout<<pos[l]<<endl;
post.push_back(pos[l]);
int main()
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>pos[i];
getpos(1,n);
if(post.size()!=n)
iff=1;
post.clear();
getpos(1,n);
if(post.size()!=n)
cout<<"NO"<<endl;
return 0;
cout<<"YES"<<endl;
for(int i=0;i<n;i++)
if(i==0)
printf("%d",post[i]);
else printf(" %d",post[i]);
return 0;
L2-005 集合相似度 (25 分)
知识点:考察对set的应用情况
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\\n",x,y);
typedef long long ll;
using namespace std;
inline int read()
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')if(ch=='-')w=-1;ch=getchar()以上是关于团体天梯练习 L2-026 小字辈的主要内容,如果未能解决你的问题,请参考以下文章