洛谷的模拟绿题
传送门 :https://www.luogu.com.cn/problem/P1065
题目中涉及的变量比较多,题目也比较难理解,最好在已经理解题目的意思后再看题解。题解写在代码段的注释里,很清晰。如果实在看不懂也可以上B站找视频。
#include<iostream> using namespace std; typedef struct infomation { int number; int time; }infomation; //infomation用来定义每个工件的每道工序的信息 //即该工序在哪个机器上以及需要花费的时间 typedef struct cur { int now; int lasttime; }cur; //cur用来定义每个工件的现在状态 //即该工件现在进行了几道工序和该工件目前工序的最晚时间 //为什么需要lasttime? //根据约束条件一,每道工序都要在前一道工序完成后才能开始 /* 例如题目中的例子,第一个工件的第一道工序已经安排好了, 在第一台机器上由0到3,那么3就是第一个工件的lasttime, 因为无论第二道工序在哪台机器上,它的开始时间都不能小于 lasttime否则违反约束一。 */ int main(void) { int m = 0, n = 0, answer = 0, order[500] = { 0 }; //m机器数,n工件数,order为安排顺序,answer存放答案 infomation info[21][21] = { 0 }; //二维数组记录每个工件的每道工序 //横向是工序号,纵向是工件号 cur pos[21] = { 0 }; bool machine[21][10000] = { 0 }; //pos数组就是每个工件当前状态 //machine的bool类型数组用来模拟机器运作 //这边定义10000是因为题目有点小坑,一个工件的每道工序 //可以在同一台机器上,题目的说明有问题 //未被占用的标false,被占用的标true //类似题目给的方案一方案二的图 scanf("%d %d", &m, &n); for (int i = 1; i <= m * n; i++) scanf("%d", &order[i]); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &info[i][j].number); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) scanf("%d", &info[i][j].time); //正常的读入,要注意读入次序 //数组都从1开始读入,这样查找的时候方便 for (int i = 1; i <= m * n; i++)//遍历order数组 { int cop = order[i]; int rank = ++pos[cop].now; int count = 0; //cop变量即工件号,rank变量即该工件当前工序 //用++的原因是pos的初始化值是0,即第0道工序 //++后变为第一道工序 //额外定义变量是为了接下来的代码更易读 //count为计数器,具体作用下面再介绍 int Number = info[cop][rank].number; int Time = info[cop][rank].time; //Number变量用来记录当前工件的工序在哪个机器上加工 //Time变量用来记录该工序花费的时间 for (int j = pos[cop].lasttime + 1;; j++) { //j变量用于操作machine数组,假如一工件的上 //一道工序的lasttime为4,那么j就要从5开始计数 //因此j=lasttime+1 if (!machine[Number][j]) count++; else count = 0; //count用来计算有多少个空位即有多少false //count表示了一个空位段的长度 //如果遇到true则count要直接清空 if (count >= Time) { for (int k = j - count + 1; k <= j; k++) machine[Number][k] = true; //如果这个空位段长度大于该工序的用时 //则把该空位段打上标记true,表明该时间段已经被占用 pos[cop].lasttime = j;//更新lasttime count = 0;//count清零,准备下一次计算 break;//找到后可以跳出循环 } } } for (int i = 1; i <= n; i++) if (pos[i].lasttime > answer) answer = pos[i].lasttime; //找到pos数组中lasttime的最大值,即为答案 printf("%d", answer); //完结撒花 return 0; }