团体程序设计天梯赛-L2题解

本文详细解析了团体程序设计天梯赛的Level 2题目,包括链表去重、月饼、二叉搜索树判断等25分题目,涵盖了数据结构和算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

团体程序设计天梯赛-L2题解

L2-002 链表去重 (25分)

//模拟
#include <bits/stdc++.h>
using namespace std;
struct node
{
   
    int key;
    int next;
} add[100005];
int f[100005];
int a1[100005], a2[100005];
int main()
{
   
    int l, n;
    cin >> l >> n;
    for (int i = 0; i < n; i++)
    {
   
        int addr;
        cin >> addr;
        cin >> add[addr].key >> add[addr].next;
    }
    int k1 = 0, k2 = 0;
    for (int i = l; i != -1; i = add[i].next)
    {
   
        if (f[abs(add[i].key)] == 0)
        {
   
            f[abs(add[i].key)] = 1;
            a1[k1++] = i;
        }
        else
        {
   
            a2[k2++] = i;
        }
    }
    if (k1)
    {
   
        for (int i = 0; i < k1 - 1; i++)
        {
   
            printf("%05d %d %05d\n", a1[i], add[a1[i]].key, a1[i + 1]);
        }
        printf("%05d %d -1\n", a1[k1 - 1], add[a1[k1 - 1]].key);
    }
    if (k2)
    {
   
        for (int i = 0; i < k2 - 1; i++)
        {
   
            printf("%05d %d %05d\n", a2[i], add[a2[i]].key, a2[i + 1]);
        }
        printf("%05d %d -1", a2[k2 - 1], add[a2[k2 - 1]].key);
    }
    return 0;
}

L2-003 月饼 (25分)

//贪心
#include <bits/stdc++.h>
using namespace std;
struct node
{
   
    double num, value, ave;
} stu[1010];
bool cmp(node a, node b)
{
   
    return a.ave > b.ave;
}
int main()
{
   
    int n;
    double d;
    cin >> n >> d;
    for (int i = 0; i < n; i++)
        cin >> stu[i].num;
    for (int i = 0; i < n; i++)
        cin >> stu[i].value;
    for (int i = 0; i < n; i++)
    {
   
        stu[i].ave = stu[i].value / stu[i].num;
    }
    sort(stu, stu + n, cmp);
    int i = 0;
    double ans = 0;
    while (d >= 0 && i < n)
    {
   
        if (d > stu[i].num)
        {
   
            d -= stu[i].num;
            ans += stu[i].value;
            i++;
        }
        else
        {
   
            ans += d * stu[i].ave;
            break;
        }
    }
    cout << fixed << setprecision(2) << ans;
    return 0;
}

L2-004 这是二叉搜索树吗? (25分)

//数据结构二叉树
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct node *BinTree;
int a[20000],b[20000],c[20000];
struct node
{
   
    int data;
    BinTree l;
    BinTree r;
};
BinTree Create(BinTree BT,int x)   //创建搜索树
{
   
    if(!BT)
    {
   
        BT=(BinTree)malloc(sizeof(struct node));
        BT->data=x;
        BT->l=BT->r=NULL;
    }
    else
    {
   
        if(x<BT->data)
            BT->l=Create(BT->l,x);
        else
            BT->r=Create(BT->r,x);
    }
    return BT;
}
int t=0;
void Pre1(BinTree BT)    // 求先序
{
   
    if(BT)
    {
   
        a[t++]=BT->data;
        Pre1(BT->l);
        Pre1(BT->r);
    }
}
int t1=0;
void Pre2(BinTree BT) //求镜像先序
{
   
    if(BT)
    {
   
        b[t1++]=BT->data;
        Pre2(BT->r);
        Pre2(BT->l);
    }
}
int f=0;
void Post1(BinTree BT)  //输出 后序
{
   
    if(BT)
    {
   
        Post1(BT->l);
        Post1(BT->r);
        if(f==0)
        {
   
            cout<<BT->data;
            f++;
        }
        else
            cout<<" "<<BT->data;
    }
}
void Post2(BinTree BT)  //输出镜像后续
{
   
    if(BT)
    {
   
        Post2(BT->r);
        Post2(BT->l);
        if(f==0)
        {
   
            cout<<BT->data;
            f++;
        }
        else
            cout<<" "<<BT->data;
    }
}
int main()
{
   
    BinTree BT=NULL;
    int N;
    cin>>N;
    for(int i=0;i<N;i++)
    {
   
        cin>>c[i];
        BT=Create(BT,c[i]);
    }
    Pre1(BT);
    Pre2(BT);
    int f1=0,f2=0;
    for(int i=0;i<N;i++)
    {
   
        if(a[i]!=c[i])  
        {
   
            f1=1;
            break;
        }
    }
    for(int i=0;i<N;i++)
    {
   
        if(b[i]!=c[i])
        {
   
            f2=1;
            break;
        }
    }
    if(f1&&f2)
    {
   
        cout<<"NO"<<endl;
    }
    else
    {
   
        cout<<"YES"<<endl;
        if(!f1)Post1(BT);
        else Post2(BT);
    }
}

L2-005 集合相似度 (25分)

//去重
#include<bits/stdc++.h>
using namespace std;
int main()
{
   
    set<int> st[500];
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
   
        int m;
        cin>>m;
        while(m--)
        {
   
            int x;
            cin>>x;
            st[i].insert(x);  //插入set中可以把一个集合的元素去重
        }
    }
    int k;
    cin>>k;
    while(k--)
    {
   
        int a,b;
        cin>>a>>b;
        double nc=0,nt;
        for(auto e:st[b])
        {
   
            if(st[a].find(e)!=st[a].end())  //从set[a]中找是否存在set[b]中元素
                nc++;
        }
        nt=st[a].size()+st[b].size()-nc;
        cout<<fixed<<setprecision(2)<<nc/nt*100<<"%"<<endl;
    }
    return 0;
}

L2-006 树的遍历 (25分)

// 数据结构 二叉数
#include <iostream>
#include <queue>
using namespace std;
struct node
{
   
    struct node *l, *r;
    int data;
};
struct node *change(int *post, int *in, int n)
{
   
    int i;
    if (n <= 0)
        return NULL;
    struct node *bt = (struct node *)malloc(sizeof(struct node));
    bt->data = post[n - 1];  //后续的最后一个数就是根
    for (i = 0; in[i] != post[n - 1]; i++);
    bt->l = change(post, in, i);
    bt->r = change(post + i, in + 1 + i, n - i - 1);
    return bt;
}
void bfs(struct node *bt)
{
   
    queue<struct node *> q;
    q.push(bt);
    int f = 0;
    while (!q.empty())
    {
   
        struct node *t = q.front();
        q.pop();
        if (f) cout << " ";
        cout << t->data, f++;
        if (t->l)
            q.push(t->l);
        if (t->r)
            q.push(t->r);
    }
}
int main()
{
   
    struct node *bt;
    int n;
    cin >> n;
    int a[110], b[110];
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < n; i++)
        cin >> b[i];
    bt = change(a, b, n);
    bfs(bt);
}

L2-007 家庭房产 (25分)

//维护size的并查集
#include <bits/stdc++.h>
using namespace std;
vector<int> p(10000);
set<int> st;
int sizep[10010]; //存家庭人口数
struct stu1 //存结果的结构体
{
   
    int no;      //家庭成员的最小编号
    double num;  // 人均房产套数
    double size; // 人均房产面积
} ans[10101];
struct stu2 //存个人信息的结构体
{
   
    int no;   //编号
    double num;  //房产套数
    double size; //总面积
} stu[10101];
bool cmp(stu1 a, stu1 b)
{
   
    if (a.size == b.size)
        return a.no < b.no;
    return a.size > b.size;
}
int find(int x)
{
   
    return p[x] == x ? x : p[x] = find(p[x]);
}
void un(int x, int y) //合并,大的编号合并到小的编号中,同时维护sizep的大小
{
   
    x = find(x), y = find(y);
    if (x != y)
    {
   
        if (x > y)
            p[x] = y,sizep[y]+=sizep[x];
        else
            p[y] = x,sizep[x]+=sizep[y];
    }
}
int main()
{
   
    int n;
    cin >> n;
    iota(p.begin(), p.end(), 0);
    for(int i=0;i<10000;i++) sizep[i]=1;
    for (int i = 0; i < n; i++)
    {
   
        int b, c;
        cin >> stu[i].no >> b >> c;
        if (b != -1) //父存在
            un(stu[i].no, b);
        if (c != -1) //母存在
            un(stu[i].no, c);
        int k;
        cin >> k;
        while (k--)
        {
   
            int x;
            cin >> x;
            un(stu[i].no, x); 
        }
        cin >> stu[i].num >> stu[i].size;
    } //边输入边合并,我们已经能正确得到了sizep的大小
    for (int i = 0; i < n; i++)  //对每个人财产进行合并
    {
   
        int id = find(stu[i].no); //返回一个家族中最小的编号,将东西都累加到最小编号上
        st.insert(id);  //可以求出最小编号的个数
        ans[id].no = id; //存最小编号
        ans[id].num += stu[i].num/sizep[id];  //求人均房产套数
        ans[id].size += stu[i].size/sizep[id];//求人均房产面积
    }
    cout << st.s
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值