今天是我第一次正式学算法(从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));//清理数据 } } 附:如果我前女友哪一天开始学算法了,希望这个对她有帮助吧!当然如果有大佬带她或是她自己很强就更好啦!