2022年CCCC天梯赛

静静的推荐

思路:

模拟应该会超时,首先可以确定的是cc超过175且pat超过s的人一定会被录取,所以这些直接加到答案里,剩下的就看各个分数有多少人,因为每个分数每次录一个最多录k次,所以每个分数最多录取的人数为min(cnt[i], k),加起来就是答案

#include <bits/stdc++.h>

using namespace std;

int n, k, s;
int cnt[300];

int main()
{
    cin >> n >> k >> s;
    
    int res = 0;
    for(int i = 1; i <= n; i ++ )
    {
        int t, p;
        cin >> t >> p;
        if(t >= 175)
        {
            if(p >= s) res ++ ;
            else cnt[t] ++ ;
        }
    }
    
    for(int i = 175; i <= 290; i ++ )
        res += min(cnt[i], k);
    
    cout << res << endl;
    
    return 0;
    
}

插松枝

思路:

大模拟,先考虑栈再考虑队列,在队列中都不满足情况还有栈和队列都不满足情况都要break

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    queue<int>q;
    stack<int>st;
    
    for(int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> x;
        q.push(x);
    }
    
    while(q.size() || st.size())
    {
        int cnt = 0, last = 100;
        bool first = true;
        while(cnt < k)
        {
            if(st.size() && st.top() <= last)
            {
                if(first)
                {
                    first = false;
                    cout << st.top();
                }
                else cout << ' ' << st.top();
                last = st.top();
                st.pop();
                cnt ++ ;
            }
            
            else if(q.size())
            {
                int t = q.front();
                if(t <= last)
                {
                    if(first) 
                    {
                        cout << t;
                        first = false;
                    }
                    else cout << ' ' << t;
                    last = t;
                    q.pop();
                    cnt ++ ;
                }
                else if(st.size() < m)
                {
                    st.push(t);
                    q.pop();
                }
                else break;
            }
            else break;
        }
        cout << endl;
    }
    return 0;
}

老板的作息表

思路:

结构体或pair排序,这里直接pair里存两个string表示起始时间和结束时间方便一些,然后直接排序,遍历找不连续区间。有两个坑点,第一个是最后的到23:59::59这个时间段,第二个是刚开始的00:00:00这个时间。

#include <bits/stdc++.h>

using namespace std;

const int N = 50010;

int main()
{
    int n;
    cin >> n;
    vector<pair<string, string>>v;
    for(int i = 0; i < n; i ++ )
    {
        string a, b, c;
        cin >> a >> b >> c;
        v.push_back({a, c});
    }
    
    sort(v.begin(), v.end());
    
    string last = "-1";
    for(auto s: v)
    {
        if(last == "-1")
        {
            if(s.first != "00:00:00") cout << "00:00:00" << " - " << s.first << endl;
            last = s.second;
        }
        else 
        {
            if(last == s.first) last = s.second;
            else 
            {
                cout << last << " - " << s.first << endl;
                last = s.second;
            }
        }
    }
    
    if(last != "23:59:59") cout << last << " - " << "23:59:59" << endl;
    
    return 0;
}

龙龙送外卖

思路:

假设我们每个外面送完都回到根节点,那假设我们一共遍历了sum条边,我们走的距离总和就是2*sum,那因为我们不用每次都回到根节点,所以我们假设最后一次送完没有回到根节点,这个结点到根节点的距离为d,那总路径就是2*sum-d,要求总路径最小,所以我们让d最大即可,即最后一次停在了离根节点最远的地方

#include <bits/stdc++.h>

using namespace std;

const int N = 100010;

int n, m;
int d[N];
int fa[N];
int sum, mx;

int dfs(int u)
{
    if(fa[u] == -1 || d[u]) return d[u];  // 到根节点了或u被搜过了
    sum ++ ;  // 边数加一,因为没有搜过
    d[u] = dfs(fa[u]) + 1;
    return d[u];
}

int main()
{
    cin >> n >> m;
    
    for(int i = 1; i <= n; i ++ ) cin >> fa[i];
    
    while(m -- )
    {
        int x;
        cin >> x;
        mx = max(mx, dfs(x));
        cout << sum * 2 - mx << endl;
    }
    return 0;
}

大众情人

思路:

首先用floyd求出所有最短距离,然后根据题意,先求出某个人的每个人对他/她最无感的距离mx,即最大值,然后由于大众情人是其中1/mx最大,所以最后所求的是所有mx的最小值,最后遍历一遍谁的mx等于这个最小值就是答案

#include <bits/stdc++.h>

using namespace std;

const int N = 510;

int n;
char sex[N];
int d[N][N];

int main()
{
    cin >> n;
    memset(d, 0x3f, sizeof d);
    for(int i = 1; i <= n; i ++ ) d[i][i] = 0;
    
    for(int i = 1; i <= n; i ++ )
    {
        cin >> sex[i];
        int k;
        cin >> k;
        while(k -- )
        {
            int id, dist;
            scanf("%d:%d", &id, &dist);
            d[i][id] = dist;
        }
    }
    
    for(int k = 1; k <= n; k ++ )
        for(int i = 1; i <= n; i ++ )
            for(int j = 1; j <= n; j ++ )
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
                
                
    for(auto c: string("FM"))
    {
        int mn = 0x3f3f3f3f;
        for(int i = 1; i <= n; i ++ )
            if(sex[i] == c)
            {
                int mx = 0;
                for(int j = 1; j <= n; j ++ )
                    if(sex[i] != sex[j])
                        mx = max(mx, d[j][i]);  // 最无感的距离
                
                mn = min(mn, mx);  // 1/d最大,所以d要最小
            }
            
        bool first = true;
        for(int i = 1; i <= n; i ++ )
            if(sex[i] == c)
            {
                int mx = 0;
                for(int j = 1; j <= n; j ++ )
                    if(sex[i] != sex[j])
                        mx = max(mx, d[j][i]);
                
                if(mx == mn)
                {
                    if(first)
                    {
                        cout << i;
                        first = false;
                    }
                    else cout << ' ' << i;
                }
            }
            
        cout << endl;
    
    }
    return 0;
}

 

posted @ 2022-07-25 16:03  彦辰kkkkk  阅读(315)  评论(0)    收藏  举报