今天是我第一次正式学算法(从acwing过来的,刚学完快排),这篇没有题解,开个头,写一篇通俗易懂的题解(大佬勿喷,嗯,估计大佬也不会来写这种题吧)
   基本思路:对到达签到点的时间排序,然后分组(就是看每支队伍是在哪一个桌子上签到),然后计算时间(后一只队伍的时间=到签到点的时间+等待时间+花费时间,只有等待时间未知,
等待时间=前一只队伍花费的时间-后一只队伍花费的时间,存在一种情况:前一支队伍完成时后一支队伍还没到,这时后一只队伍等待时间为0)
   
   代码如下
#include<bits/stdc++.h>
using namespace std;
const int N = 10005;
int n, p[N], t, wait, d;//wait表示等待的时间,t就是测试数据的组数了,wait表示每只队伍等待的时间,n指队伍数,d指花费的时间

//快排
void quicksort(int p[], int l, int r)
{
    if (l >= r)return;
    int x = p[(l + r) / 2], i = l - 1, j = r + 1;
    while (i < j)
    {
        do i++; while (p[i] < x);
        do j--; while (p[j] > x);
        if (i < j)swap(p[i], p[j]);
    }
    quicksort(p, l, j);
    quicksort(p, j + 1, r);
}
int main()
{
    cin >> t;
    while (t--)
    {
        vector<vector<int>>table(4, vector<int>());//构建三张桌子,采用局部比较好,不然每组数据都要清0(fill),太麻烦了
        cin >> n;//签到队伍数
        for (int i = 0; i < n; i++)cin >> p[i];//最好用scanf,读取更快
        cin >> d;
        quicksort(p, 0, n - 1);
        for (int i = 0; i < n; i++)table[i % 3 + 1].push_back(p[i]);//分组
        for (int i = 0; i < table[(n - 1) % 3 + 1].size() - 1; i++)
        {
            int time = table[(n - 1) % 3 + 1][i] + wait + d;//计算当前队伍完成的时间
            if (time > table[(n - 1) % 3 + 1][i + 1])
                wait = time - table[(n - 1) % 3 + 1][i + 1];
            else wait = 0;//更新下一只队伍需要的等待时间
        }//其实这个循环体可以用递推或是dp来写
        cout << table[(n - 1) % 3 + 1][table[(n - 1) % 3 + 1].size() - 1] + d + wait << endl;//计算最后一只队伍的等待时间
        wait = 0;
        memset(p, 0, sizeof(p));//清理数据
    }
}

附:如果我前女友哪一天开始学算法了,希望这个对她有帮助吧!当然如果有大佬带她或是她自己很强就更好啦!