package com.dota; import com.dota.domain.Doctor; import com.dota.domain.Week; import com.dota.domain.WorkEnum; import java.util.Arrays; public class Main { static Doctor gl; static Doctor zl; static Doctor ttt; static Doctor zy; static Doctor ln; static Doctor zh; static Doctor tgy; public static void main(String[] args) { init(); var doctorOrder = new Doctor[]{ gl, zl, ttt, zy, ln, zh }; var outputOrder = new Doctor[]{ ln, zy, ttt, zl, zh, gl, tgy }; for (int i = 0; i < 2; i++) { schedule(doctorOrder, outputOrder); } } static void init() { gl = new Doctor("顾磊"); gl.group = 1; zl = new Doctor("章亮"); zl.opd = 3; zl.works[3] = WorkEnum.OPD; ttt = new Doctor("唐婷婷"); ttt.opd = 2; ttt.works[2] = WorkEnum.OPD; zy = new Doctor("杨祖怡"); zy.group = 1; ln = new Doctor("李宁"); ln.opd = 4; ln.works[4] = WorkEnum.OPD; zh = new Doctor("周晖"); zh.opd = 1; zh.works[1] = WorkEnum.OPD; tgy = new Doctor("田国燕"); tgy.opd = 0; tgy.group = 0; tgy.works[0] = WorkEnum.OPD; zh.swap = gl; ttt.swap = zl; } static void schedule(Doctor[] doctors, Doctor[] outputOrder) { // 日期 int days = 0; // 医生下标 int idx = 0; for (int k = 0; k < 2; k++) { for (int i = 0; i < 7; i++) { var d = doctors[idx]; if (d.firstRest) { d.firstRest = false; d.works[0] = WorkEnum.HOLIDAY; } // 值班第二天是值休 // 周六值班有两天额外休息 if (i == 5) { d.restCount = 2; d.works[6] = WorkEnum.HOLIDAY; } else if (i == 4) { //周五值班有额外一天休息 d.works[5] = WorkEnum.HOLIDAY; d.restCount = 1; } else if (i == 6) { // 周日值班有一天额外休息 d.restCount = 1; d.firstRest = true; } else { d.works[days + 1] = WorkEnum.HOLIDAY; } if (d.works[days] == WorkEnum.OPD) { d.works[days] = WorkEnum.OPD_AND_DUTY; } else { d.works[days] = WorkEnum.DUTY; } days = (days + 1) % 7; idx = (idx + 1) % doctors.length; } fix(doctors); rest(doctors); print(outputOrder); for (Doctor d : doctors) { d.reset(); } } } // 给有调休的安排休息 // 保证同一组必须有一个在 static void rest(Doctor[] doctors) { for (Doctor doctor : doctors) { if (doctor.lastRestCount == 0) { continue; } int count = 0; for (int j = 0; j < 5; j++) { if (checkRest(j, doctor, doctors)) { doctor.works[j] = WorkEnum.REST; count++; } if (count==doctor.lastRestCount) { break; } } } for (Doctor doctor : doctors) { doctor.lastRestCount = doctor.restCount; } } // 判断是否有门诊和值班冲突,有的话调整一下 // 冲突的情况是前一天值班,门诊那天变调休了,因此没有门诊或者门诊值班的安排 static void fix(Doctor[] doctors) { for (Doctor d : doctors) { if (d.name.equals("杨祖怡") || d.name.equals("顾磊")) { continue; } if (Arrays.stream(d.works).anyMatch(workEnum -> workEnum == WorkEnum.OPD || workEnum == WorkEnum.OPD_AND_DUTY)) { continue; } if (d == ln) { ln.works[3] = WorkEnum.OPD_AND_DUTY; zl.works[3] = WorkEnum.WORK; zl.works[4] = WorkEnum.OPD; } if (d == zl) { ln.works[3] = WorkEnum.OPD; zl.works[4] = WorkEnum.OPD; } // 周晖固定周二门诊,所以不能周一值班 if (d == zh) { zh.works[0] = WorkEnum.WORK; zh.works[1] = WorkEnum.OPD; // 和顾磊换值班 int t = getDuty(gl); zh.works[t] = gl.works[t]; if (t < 6) { zh.works[t + 1] = gl.works[t + 1]; } if (t < 4) { gl.works[t] = WorkEnum.WORK; gl.works[t + 1] = WorkEnum.WORK; } if (t == 4) { zh.restCount = 1; gl.restCount = 0; gl.works[4] = WorkEnum.WORK; gl.works[5] = WorkEnum.REST; } if (t == 5) { zh.restCount = 2; gl.restCount = 0; gl.works[5] = WorkEnum.REST; gl.works[6] = WorkEnum.REST; } if (t == 6) { zh.restCount = 1; zh.firstRest = true; gl.restCount = 0; gl.firstRest = false; gl.works[6] = WorkEnum.REST; } gl.works[0] = WorkEnum.DUTY; gl.works[1] = WorkEnum.HOLIDAY; } // 唐婷婷固定周三门诊,周二值班的话和章亮换一下 if (d == ttt) { ttt.works[1] = WorkEnum.WORK; ttt.works[2] = WorkEnum.OPD; //和章亮换值班 int t = getDuty(zl); ttt.works[t] = zl.works[t]; if (t < 6) { ttt.works[t + 1] = zl.works[t + 1]; } if (t < 4) { zl.works[t] = WorkEnum.WORK; zl.works[t + 1] = WorkEnum.WORK; } else if (t == 4) { ttt.restCount = 1; zl.restCount = 0; zl.works[4] = WorkEnum.WORK; zl.works[5] = WorkEnum.REST; } else if (t == 5) { ttt.restCount = 2; zl.restCount = 0; zl.works[5] = WorkEnum.REST; zl.works[6] = WorkEnum.REST; } else if (t == 6) { ttt.restCount = 1; ttt.firstRest = true; zl.restCount = 0; zl.firstRest = false; zl.works[6] = WorkEnum.REST; } zl.works[1] = WorkEnum.DUTY; zl.works[2] = WorkEnum.HOLIDAY; } } } static int getDuty(Doctor d) { for (int i = 0; i < d.works.length; i++) { if (d.works[i] == WorkEnum.DUTY) { return i; } } return -1; } //判断某天是否可以休息 //祖怡和顾磊是一组,其他人是一组 static boolean checkRest(int day, Doctor doctor, Doctor[] doctors) { // 只有日班才会安排休息 if (doctor.works[day] != WorkEnum.WORK) { return false; } for (Doctor d : doctors) { if (doctor.group == d.group) { var w = d.works[day]; if (w == WorkEnum.WORK || w == WorkEnum.OPD || w == WorkEnum.DUTY || w == WorkEnum.OPD_AND_DUTY) { return true; } } } return false; } static void print(Doctor[] outputOrder) { System.out.printf("%10s", " "); for (Week value : Week.values()) { System.out.printf("%10s", value.getValue()); } System.out.println(" "); for (Doctor doctor : outputOrder) { System.out.printf("%10s", doctor.name); for (WorkEnum work : doctor.works) { System.out.printf("%10s", work.getName()); } System.out.println(" "); } System.out.println(" "); } }