Algorithm Notebook 3(3.1.2026~3.31.2026)

本文最后更新于 2026年3月3日 上午

Luogu P1065 - 作业调度方案

题意:有n个步骤和机器,m个工件要进行作业调度,每个工件需要按照步骤1到n的顺序进行加工,每个步骤只能在特定的机器上进行,求按照指定的顺序完成所有工件的时间(题目要求从最早的地方开始)。

思路:使用计算机模拟填表的过程,使用finish[]记录每一个工件在操作的这一步之前完成的最后的截止时间,now_op记录现在在操作的工件的最新操作步骤,每次调度从finish[op]开始寻找最先的满足条件的时间点,更新finish[op]。

难点:难点在于可能会忽视题目特别提醒了的不可以先加工后面的步骤,应该先完成前面的步骤才能够完成后面的步骤,导致在寻找满足条件的时间点时没有考虑到这个限制条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;
const int MAXN = 20 + 5;
const int MAXT = 1e4;
struct workpiece{
int machine[MAXN], time[MAXN];
}wp[MAXN];
int order[MAXN * MAXN], finish[MAXN], now_op[MAXN], machine[MAXN][MAXT];
int main(){
int n, m, ans;
cin >> m >> n;
for (int i = 1; i <= n * m; i++) cin >> order[i];
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> wp[i].machine[j];
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> wp[i].time[j];

for (int i = 1; i <= n * m; i++){
int op = order[i];
int step = ++now_op[op];
int machine_now = wp[op].machine[step];
int time_needed = wp[op].time[step];

int t = finish[op] + 1;
while(true){
bool flag = false;
for (int j = t; j <= t + time_needed - 1; j++){
if (machine[machine_now][j]) break;
if (j == t + time_needed - 1) flag = true;
}
if (flag) break;
else t++;
}
for (int j = t; j <= t + time_needed - 1; j++) machine[machine_now][j] = true;
finish[op] = t + time_needed - 1;
ans = max(ans, finish[op]);
}
cout << ans;
}

Luogu P1786 帮贡排序

题意:有n个人,每个人有姓名、职务、帮贡和等级,按照帮贡从大到小排序,如果帮贡相同则按照输入顺序排序,输出排序后的结果。

思路:定义一个结构体来存储每个人的信息,使用sort函数进行排序,排序时按照帮贡从大到小排序,如果帮贡相同则按照输入顺序排序。

难点:一开始要忽略帮主和副帮主。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 110 + 5;
struct Person{
int contribution, level, rank;
string position, name;
};
string pos[] = {"","BangZhu","FuBangZhu","HuFa","ZhangLao","TangZhu","JingYing","BangZhong"};
int get_(string x){
for (int i = 1; i <= 7; i++) if (pos[i] == x) return i;
return 100;
}
int main(){
int n;
vector<Person> a, temp;
cin >> n;
for (int i = 1; i <= n; i++){
int contribution, level, rank = i; string name, position;
cin >> name >> position >> contribution >> level;
Person p = {contribution, level, rank, position, name};
if (position != "BangZhu" && position != "FuBangZhu")
a.push_back(p);
else temp.push_back(p);
}
sort(a.begin(), a.end(), [](const Person &a, const Person &b){
if (a.contribution != b.contribution) return a.contribution > b.contribution;
else if (a.rank != b.rank) return a.rank < b.rank;
else return false;
});
// for (int i = 0; i < n - 3; i++){
// int cnt = i + 1; // 第cnt名(按帮贡排序后)
// if (cnt <= 2) a[i].position = "HuFa";
// else if (cnt <= 6) a[i].position = "ZhangLao";
// else if (cnt <= 13) a[i].position = "TangZhu";
// else if (cnt <= 38) a[i].position = "JingYing";
// else a[i].position = "BangZhong";
// }
int cnt = 0;
for (Person &p : a){
cnt++;
if (cnt <= 2) p.position = "HuFa";
else if (cnt <= 6) p.position = "ZhangLao";
else if (cnt <= 13) p.position = "TangZhu";
else if (cnt <= 38) p.position = "JingYing";
else p.position = "BangZhong";
}
for (Person p : temp) a.push_back(p);
sort(a.begin(), a.end(), [](const Person &a, const Person &b){
if (a.position != b.position) return get_(a.position) < get_(b.position);
else if (a.level != b.level) return a.level > b.level;
else if (a.rank != b.rank) return a.rank < b.rank;
else return false;
});
for (Person p : a) cout << p.name << " " << p.position << " " << p.level << endl;
return 0;
}
1
for (Person &p : a)

是C++11引入的范围for循环,使用引用可以避免不必要的复制,提高效率。

1
2
3
4
5
6
sort(a.begin(), a.end(), [](const Person &a, const Person &b){
if (a.position != b.position) return get_(a.position) < get_(b.position);
else if (a.level != b.level) return a.level > b.level;
else if (a.rank != b.rank) return a.rank < b.rank;
else return false;
});

这是使用lambda表达式作为排序的比较函数,按照职位、等级和输入顺序进行排序。

其中

1
[](const Person &a, const Person &b)

是一个匿名函数,接受两个Person对象作为参数,返回一个bool值,表示a是否应该排在b前面。


Algorithm Notebook 3(3.1.2026~3.31.2026)
https://www.mirstar.net/2026/03/01/alogorithm-notebook-3/
作者
onlymatt
发布于
2026年3月1日
许可协议