天梯赛练习题L2(006-010)

L2-006 树的遍历

  • 先序遍历:根→左→右
  • 中序遍历:左→根→右
  • 后序遍历:左→右→根
  • 层序遍历:按照每层顺序遍历
  • 根据后序遍历和中序遍历,可以知道:
  • 1.后序遍历的最后一个值,一定是根节点;
  • 2.此根节点在中序遍历中,将左右子树划分开来;
  • 3.在左右子树中,对应的区间结点数一定是相同的,于是再重复1.2.的过程即可;
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
LL n,post[N],in[N];
map<LL,LL> L,R;
int dfs(int l1,int r1,int l2,int r2)
{
    if(l1>r1) return 0;
    int root=post[r1];
    int mid;
    for(mid=l2;mid<=r2&&in[mid]!=root;mid++) ;

    L[root]=dfs(l1,l1-l2+mid-1,l2,mid-1);
    R[root]=dfs(r1-r2+mid,r1-1,mid+1,r2);
    return root;
}
void bfs(int root)
{
    queue<int> q;
    q.push(root);
    bool flag=false;
    while(!q.empty())
    {
        int top=q.front();
        if(flag) cout<<" ";
        cout<<top;
        flag=true;
        q.pop();
        if(L[top]) q.push(L[top]);
        if(R[top]) q.push(R[top]);
    }
    cout<<endl;
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++)//后序遍历
            cin>>post[i];
        for(int i=0;i<n;i++)//中序遍历
            cin>>in[i];
        bfs(dfs(0,n-1,0,n-1));
    }
    return 0;
}

L2-007 家庭房产

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
LL num[N],sum[N],father[N],vis[N];
struct node
{
    LL minn,people,avgwu,avgsum;
    double x1,x2;
    const bool operator<(const node &A) const {
        if(A.x2==x2) return minn<A.minn;
        return x2>A.x2;
    }
}a[N];
int find(int x)
{
    if(father[x]!=x) father[x]=find(father[x]);
    return father[x];
}
void merge(int x,int y)
{
    LL fx=find(x),fy=find(y);
    if(fx>fy) father[fx]=fy;
    else father[fy]=fx;
}
int main()
{
    //cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        for(int i=0;i<=9999;i++)
            father[i]=i;
        while(n--)
        {
            LL idx,fa,ma,zi;
            cin>>idx>>fa>>ma>>zi;
            vis[idx]=1;
            if(fa!=-1) merge(idx,fa),vis[fa]=1;
            if(ma!=-1) merge(idx,ma),vis[ma]=1;
            while(zi--)
            {
                LL x;
                cin>>x;
                merge(idx,x);
                vis[x]=1;
            }
            cin>>num[idx]>>sum[idx];
        }
        for(int i=0;i<=9999;i++)
        {
            if(vis[i]==1)
            {
                LL fi=find(i);
                a[fi].people++;
                a[fi].avgwu+=num[i];
                a[fi].avgsum+=sum[i];
            }
        }
        vector<node> v;
        for(int i=0;i<=9999;i++)
        {
            if(vis[i]&&find(i)==i)
            {
                a[i].minn=i;
                a[i].x1=a[i].avgwu*1.0/a[i].people;
                a[i].x2=a[i].avgsum*1.0/a[i].people;
                v.push_back(a[i]);
            }
        }
        sort(v.begin(),v.end());
        cout<<v.size()<<endl;
        for(int i=0;i<v.size();i++)
        {
            printf("%04d %d %.3lf %.3lf\n",v[i].minn,v[i].people,v[i].x1,v[i].x2);
        }
    }
    return 0;
}

L2-008 最长对称子串

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        string s;
        getline(cin,s);
        LL maxn=1;
        for(int i=0;i<s.size();i++)
        {
            LL l=i,r=i+1;
            while(l>=0&&r<s.size()&&s[l]==s[r])
            {
                maxn=max(maxn,r-l+1);
                l--,r++;
            }
            l=i-1,r=i+1;
            while(l>=0&&r<s.size()&&s[l]==s[r])
            {
                maxn=max(maxn,r-l+1);
                l--,r++;
            }
        }
        cout<<maxn<<endl;
    }
    return 0;
}

L2-009 抢红包

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
LL n;
struct node
{
    LL idx;
    LL sum;
    LL num;
}a[N];
bool cmp(node l,node r)
{
    if(l.sum!=r.sum) return l.sum>r.sum;
    else if(l.num!=r.num) return l.num>r.num;
    else return l.idx<r.idx;
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            a[i].idx=i;
        }
        for(int i=1;i<=n;i++)
        {
            LL x;
            cin>>x;
            while(x--)
            {
                LL who,money;
                cin>>who>>money;
                a[who].sum+=money;
                a[who].num++;
                a[i].sum-=money;
            }
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            printf("%d %.2lf\n",a[i].idx,a[i].sum*1.0/100);
        }
    }
    return 0;
}

L2-010 排座位

为什么要用并查集?因为朋友关系具有传递性

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
LL n,m,q,father[N];
LL g[M][M];
int find(int x)
{
    if(father[x]!=x) father[x]=find(father[x]);
    return father[x];
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL n,m,q;
        cin>>n>>m>>q;
        memset(g,0,sizeof g);
        for(int i=1;i<=n;i++)
        {
            father[i]=i;
        }
        while(m--)
        {
            LL x,y,z;
            cin>>x>>y>>z;
            g[x][y]=g[y][x]=z;
            if(z==1)
            {
                father[find(x)]=find(y);
            }
        }
        while(q--)
        {
            LL x,y;
            cin>>x>>y;
            if(g[x][y]==1) cout<<"No problem"<<endl;
            else if(g[x][y]==-1)
            {
                LL fx=find(x);
                LL fy=find(y);
                if(fx==fy) cout<<"OK but..."<<endl;
                else cout<<"No way"<<endl;
            }
            else cout<<"OK"<<endl;
        }
    }
    return 0;
}
posted @ 2022-12-27 10:57  Vijurria  阅读(22)  评论(0编辑  收藏  举报