天梯赛2021

L2-041 插松枝

模拟

#include <iostream>
#include <cstring>
#include <stack>
#include <queue>
 
using namespace  std;
 
int n, m, k;
queue<int> q;
stack<int> s;

void solve()
{
    while (1)
    {
        vector<int> v;
        bool flag = 0;
        while(1)
        {
            if (v.empty())
            {
                if (!s.empty())
                {
                    v.push_back(s.top());
                    s.pop();
                }
                else if (!q.empty())
                {
                    v.push_back(q.front());
                    q.pop();
                }
                else
                {
                    break;
                }
            }
            else
            {
                if (!s.empty() && s.top() <= v.back())
                {
                    v.push_back(s.top());
                    s.pop();
                }
                else
                {
                    while (!q.empty() && s.size() <= m)
                    {
                        auto t = q.front();
                        if (t <= v.back())
                        {
                            q.pop();
                            v.push_back(t);
                            break;
                        }
                        else
                        {
                            if (s.size() == m)
                            {
                                flag = 1;
                                break;
                            }
                            else
                            {
                                s.push(t);
                                q.pop();
                            }
                        }
                    }
                    if (q.empty() && (s.empty() || s.top() > v.back()))
                    {
                        break;
                    }
                }
            }
            if (flag || v.size() == k)
            {
                break;
            }
        }
        for (int i = 0; i < v.size(); i ++ )
        {
            if (i != v.size() - 1)
            {
                cout << v[i] << ' ';
            }
            else
            {
                cout << v[i] << endl;
            }
        }
        if(s.empty() && q.empty())
        {
            break;
        }
    }
    return;
}
 
int main()
{
    cin >> n >> m >> k;
    for (int i = 0; i < n; i ++ )
    {
        int x;
        cin >> x;
        q.push(x);
    }
    solve();
    return 0;
}

L2-042 老板的作息表

排序 + 模拟

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 2e5 + 10;

int n,m;

struct L
{
    int hh,mm,ss;
}a[N],b[N];


struct LL
{
    int l,r;
}t[N];

bool cmp(struct LL x,struct LL y)
{
    if(x.l == y.l )
    {
        return x.r < y.r;
    }
    return x.l < y.l;
}

int main()
{
    cin >> n;
    for(int i = 1 ;i <= n; i ++)
    {
        scanf("%d:%d:%d - %d:%d:%d",&a[i].hh,&a[i].mm,&a[i].ss,&b[i].hh,&b[i].mm,&b[i].ss);
        t[i].l = a[i].hh * 60 * 60 + a[i].mm * 60 + a[i].ss;
        t[i].r = b[i].hh * 60 * 60 + b[i].mm * 60 + b[i].ss;
    }
    t[0] = {0,0};
    t[n+1] = {24 * 60 * 60 - 1,24 * 60 * 60 - 1};
    sort(t + 1,t + n + 1,cmp);
    for(int i = 1; i <= n + 1; i ++)
    {
        if(t[i].l > t[i - 1].r)
        {
            printf("%02d:%02d:%02d -",t[i - 1].r / 3600,t[i - 1].r % 3600 / 60,t[i - 1].r % 60);
            printf(" %02d:%02d:%02d\n",t[i].l / 3600,t[i].l % 3600 / 60,t[i].l % 60);
        }
    }  
    return 0;
}

L2-043 龙龙送外卖

从根节点出发,最短距离d = 走过的路径长度 * 2 - 最大深度

#include<iostream>
#include<cstring>
using namespace std;
const int N = 5e5+10;

int n,m,k;

int fa[N],dep[N];

int dis;

int dfs(int u)
{
    if(fa[u] == -1 || dep[u])
    {
        return dep[u];
    }
    dis ++;
    dep[u] = dfs(fa[u]) + 1;
    return dep[u];
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i ++)
    {
        cin >> fa[i];
    }
    int d = 0,ans = 0;
    for(int i = 1; i <= m; i ++)
    {
        int t;
        cin >> t;
        int cnt = dfs(t);
        d = max(d,dep[t]);
        ans = dis * 2 - d;
        cout << ans << endl;
    }
    return 0;
}

L2-044 大众情人

弗洛伊德最短路径更新最短路径,再更新每个人的异性缘,更新同性内的最大异性缘;

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

const int N = 2e5 + 10;

int n;
vector<int> ans1,ans2;

int f[510][510];

int ff = 1e9,mm = 1e9;

int dis[N];

char st[N];

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
        {
            if(i == j)
                f[i][j] = 0;
            else
                f[i][j] = 1e9;
        }
    }
    for(int i = 1; i <= n; i ++)
    {
        int t;
        char ch;
        cin >> ch >> t;    
        st[i] = ch;
        for(int j = 1; j <= t; j ++)
        {
            int a,b;
            scanf("%d:%d",&a,&b);
            f[i][a] = b;
        }    
    }
    for(int k = 1; k <= n; k ++)
    {
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= n; j ++)
            {
                f[i][j] = min(f[i][j],f[i][k]+f[k][j]);
            }
        }
    }
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1;  j <= n; j ++)
        {
            if(st[i] != st[j])
            {
                dis[i] = max(dis[i],f[j][i]);
            }
        }
    }
    for(int i = 1; i <= n; i ++)
    {
        if(st[i] == 'F')
        {
            ff = min(ff,dis[i]);
        }
        else
        {
            mm = min(mm,dis[i]);
        }
    }
    for(int i = 1; i <= n; i ++)
    {
        if(st[i] == 'F' && dis[i] == ff)
        {
            ans1.push_back(i);
        }
    }
    for(int i = 1; i <= n; i ++)
    {
        if(st[i] == 'M' && dis[i] == mm)
        {
            ans2.push_back(i);
        }
    }
    for(int i = 0; i < ans1.size(); i ++)
    {
        if(i) cout << " ";
        cout << ans1[i];
    }
    cout << endl;
    for(int i = 0; i < ans2.size(); i ++)
    {
        if(i) cout << " ";
        cout << ans2[i];
    }
    return 0;
}

L3-031 千手观音

拓扑排序,建图很麻烦,具体看代码

#include <iostream>
#include <cstring>
#include <queue>
#include <map>
#include <string>
#include <vector>
using namespace std;

const int N = 1e5 + 10;

int n,m,idx = 1;

int r[N],v[N];

char t[20];

map<string,int> mp1;
map<int,string> mp2;

vector<int> g[N],ans;

string s,ver[N][10];

struct node
{
    int x;
    friend bool operator < (node a,node b) 
    {
        return mp2[a.x] > mp2[b.x];
    }
};

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        scanf("%s",&t);
        int la = strlen(t);
        for(int j = 0; j < la; j ++)
        {
            if(t[j] == '.') 
                v[i] ++;
            else
                ver[i][v[i]] +=(t[j]);
        }
        for(int j = 0; j <= v[i]; j ++)
        {
            if(!mp1[ver[i][j]])
            {
                mp1[ver[i][j]] = idx;
                mp2[idx] = ver[i][j];
                idx ++;
            }
        }
        if(i != 1 && v[i] == v[i - 1])
        {
            for(int j = 0; j <= v[i]; j ++)
            {
                if(ver[i][j] != ver[i - 1][j])
                {
                    g[mp1[ver[i - 1][j]]].push_back(mp1[ver[i][j]]);
                    r[mp1[ver[i][j]]] ++;
                    break;
                }
            }
        }
    }
    priority_queue<node> q;
    for(int i = 1; i < idx; i ++)
    {
        if(!r[i])
        {
            q.push({i});
        }
    }
    while(!q.empty())
    {
        int u = q.top().x;
        q.pop();
        for(int i = 0; i < g[u].size(); i ++)
        {
            int v = g[u][i];
            r[v] --;
            if(!r[v])
            {
                q.push({v});
            }
        }
        ans.push_back(u);
    }
    n = ans.size();
    for(int i = 0; i < n; i ++)
    {
        cout << mp2[ans[i]];
        if(i < n - 1) cout << ".";
    }
    return 0;
}

L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事

#include <iostream>
#include <cstring>
#define int long long
using namespace std;

const int N = 3e5 + 10;

const int mod = 1e9 + 7;

int n,m;

int son = 1,ans,er = 500000004;

int e[N * 2],ne[N * 2],h[N * 2],idx;

void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}

int lowbit(int x)
{
    return x&(-x);
}

int c[N];

void modify(int x,int k)
{
    for(int i = x; i <= n; i += lowbit(i))
    {
        c[i] += k;
    }
}

int quiry(int x)
{
    int cnt = 0;
    for(int i = x; i ; i -= lowbit(i))
    {
        cnt += c[i];
    }
    return cnt;
}

int si[N],dep[N];

void dfs(int u,int f)
{
    si[u] = 1;
    dep[u] = dep[f] + 1;
    int cnt = quiry(n - u + 1);
    int x = 1, y = 1;
    ans = (ans + cnt) % mod;
    modify(n - u + 1,1);
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int v = e[i];
        if(v == f)
        {
            continue;
        }    
        x = x * y % mod;
        y ++;
    
        dfs(v,u);
        si[u] += si[v];
    }
    if(x > 1) son = son * x % mod;
    modify(n - u + 1, -1);
    return;
    
}

signed main()
{
    memset(h,-1,sizeof h);
    int root;
    cin >> n >> root;
    for(int i = 1; i < n; i ++) 
    {
        int a,b;
        cin >> a >> b;
        add(a,b);
        add(b,a);
    }
    dfs(root,-1);
    ans = ans * son % mod;
    for(int i = 1; i <= n; i ++)
    {
        int x = n - dep[i] - si[i] + 1;
        ans = (ans + x * son % mod * er % mod * er % mod) % mod;
    }
    cout << ans << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值