uva212 java

77 阅读2分钟

import java.io.; import java.util.;

interface Printer { void p(Object... o);

void pn(Object... o);

default String format(Object... o) {
    String format;
    if (o.length == 1) {
        format = o[0].toString();
    } else {
        Object[] dest = new Object[o.length - 1];
        System.arraycopy(o, 1, dest, 0, dest.length);
        format = String.format(o[0].toString(), dest);
    }
    return format;
}

}

class MyPrinter implements Printer { @Override public void p(Object... o) { printToFile(false, o); System.out.print(format(o)); }

@Override
public void pn(Object... o) {
    printToFile(true, o);
    if (o == null || o.length == 0) {
        System.out.println();
    } else {
        System.out.println(format(o));
    }
}

private void printToFile(boolean nl, Object... o) {
    if (writer == null) {
        return;
    }
    try {
        if (o.length != 0) {
            writer.write(format(o));
        }
        if (nl) {
            writer.write("\n");
        }
        writer.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private static FileWriter writer;

static {
    if ("true".equals(System.getenv("OUTPUT_TO_LOCAL"))) {
        try {
            writer = new FileWriter("D:\\output.txt");
            writer.write("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

}

public class Main {

public static void main(String[] args) {
    solution(System.in, new MyPrinter());
}

public static void solution(InputStream in, Printer p) {
    Scanner scanner = new Scanner(in);
    while (scanner.hasNextLine()) {
        // Number of operating rooms (maximum of 10)
        // Number of recovery room beds (maximum of 30)
        // Starting hour for 1st surgery of day (based on a 24-hour clock)
        // Minutes to transport patient from operating room to recovery room
        // Minutes to prepare operating room for next patient
        // Minutes to prepare recovery room bed for next patient
        // Number of surgery patients for the day (maximum of 100)
        int opRoomCount = scanner.nextInt();
        int rcRoomCount = scanner.nextInt();
        int startHour = scanner.nextInt();
        int mFromOpToRc = scanner.nextInt();
        int mPreOpRoom = scanner.nextInt();
        int mPreRcRoom = scanner.nextInt();
        int patientCount = scanner.nextInt();
        scanner.nextLine();
        LinkedList<Patient> psOp = new LinkedList<>();
        ArrayList<Patient> ps = new ArrayList<>();
        HashMap<Integer, Patient> idPatientMap = new HashMap<>();
        for (int i = 0; i < patientCount; i++) {
            String name = scanner.nextLine();
            int opTime = scanner.nextInt();
            int rcTime = scanner.nextInt();
            Patient patient = new Patient(i, name, opTime, rcTime);
            psOp.add(patient);
            ps.add(patient);
            idPatientMap.put(i, patient);
            scanner.nextLine();
        }
        PriorityQueue<Event> events = new PriorityQueue<>();
        TreeSet<Integer> availableOpRoom = new TreeSet<>();
        TreeMap<Integer, Integer> opRecord = new TreeMap<>();
        TreeMap<Integer, Integer> rcRecord = new TreeMap<>();
        for (int i = 0; i < opRoomCount; i++) {
            availableOpRoom.add(i);
            events.add(new Event(Event.EVENT_OP_FREE, i, 0, -1));
        }
        TreeSet<Integer> availableRcRoom = new TreeSet<>();
        for (int i = 0; i < rcRoomCount; i++) {
            availableRcRoom.add(i);
            events.add(new Event(Event.EVENT_RC_FREE, i, 0, -1));
        }
        int currentTimeMin = 0;
        while (!events.isEmpty()) {
            Event event = events.poll();
            currentTimeMin = event.happenTime;
            switch (event.type) {
                case Event.EVENT_OP_FREE:
                    // put patient to rc room
                    if (event.patientId >= 0) {
                        Patient patient = idPatientMap.get(event.patientId);
                        patient.rcRoom = availableRcRoom.pollFirst();
                        patient.rcStTime = currentTimeMin + mFromOpToRc;
                        patient.rcEdTime = patient.rcStTime + patient.rcTime;
                        events.add(new Event(Event.EVENT_RC_FREE, patient.rcRoom, patient.rcEdTime + mPreRcRoom, patient.id));
                        rcRecord.put(patient.rcRoom, rcRecord.computeIfAbsent(patient.rcRoom, it -> 0) + patient.rcTime);
                    }
                    // put another patient to op room
                    availableOpRoom.add(event.roomId);
                    if (!psOp.isEmpty()) {
                        Patient patient = psOp.pop();
                        patient.opRoom = availableOpRoom.pollFirst();
                        patient.opStTime = event.patientId < 0 ? currentTimeMin : currentTimeMin + mPreOpRoom;
                        patient.opEdTime = patient.opStTime + patient.opTime;
                        events.add(new Event(Event.EVENT_OP_FREE, patient.opRoom, patient.opEdTime, patient.id));
                        opRecord.put(patient.opRoom, opRecord.computeIfAbsent(patient.opRoom, it -> 0) + patient.opTime);
                    }
                    break;
                case Event.EVENT_RC_FREE:
                    availableRcRoom.add(event.roomId);
                    break;
            }
        }
        currentTimeMin -= mPreRcRoom;

        p.p(" Patient          Operating Room          Recovery Room\n" +
                " #  Name     Room#  Begin   End      Bed#  Begin    End\n" +
                " ------------------------------------------------------\n");
        for (Patient patient : ps) {
            p.pn(patient.toString(startHour));
        }

        p.pn();

        p.p("Facility Utilization\n" +
                "Type  # Minutes  % Used\n" +
                "-------------------------\n");
        for (int i = 0; i < opRoomCount; i++) {
            p.pn(String.format("Room %2d%8d   %5.2f", i + 1, opRecord.computeIfAbsent(i, it -> 0), opRecord.computeIfAbsent(i, it -> 0) * 100.0 / currentTimeMin));
        }
        for (int i = 0; i < rcRoomCount; i++) {
            p.pn(String.format("Bed  %2d%8d   %5.2f", i + 1, rcRecord.computeIfAbsent(i, it -> 0), rcRecord.computeIfAbsent(i, it -> 0) * 100.0 / currentTimeMin));
        }

        p.pn();
    }
}

}

class Event implements Comparable {

static final int EVENT_OP_FREE = 0, EVENT_OP_USE = 1, EVENT_RC_FREE = 2, EVENT_RC_USE = 3;

int type, happenTime, roomId, patientId = -1;

Event(int type, int roomId, int happenTime, int patientId) {
    this.type = type;
    this.roomId = roomId;
    this.happenTime = happenTime;
    this.patientId = patientId;
}

@Override
public int compareTo(Event o) {
    int time = happenTime - o.happenTime;
    if (time != 0) {
        return time;
    }
    int typeDiff = o.type - type;
    if (typeDiff != 0) {
        return typeDiff;
    }
    return roomId - o.roomId;
}

}

class Patient {

String name;
int id, opTime, rcTime, opRoom, rcRoom, opStTime, rcStTime, opEdTime, rcEdTime;

public Patient(int id, String name, int opTime, int rcTime) {
    this.id = id;
    this.name = name;
    this.opTime = opTime;
    this.rcTime = rcTime;
}

public String toString(int startTimeHour) {
    // 1 Jones 1 7:00 7:28 3 7:33 9:53
    StringBuilder builder = new StringBuilder();
    int opStH = startTimeHour + opStTime / 60;
    int opStM = opStTime % 60;
    int opEdH = startTimeHour + opEdTime / 60;
    int opEdM = opEdTime % 60;
    int rcStH = startTimeHour + rcStTime / 60;
    int rcStM = rcStTime % 60;
    int rcEdH = startTimeHour + rcEdTime / 60;
    int rcEdM = rcEdTime % 60;
    return String.format("%2d  %-9s%3d   %2d:%02d   %2d:%02d     %2d   %2d:%02d   %2d:%02d"
            , id + 1, name, opRoom + 1, opStH, opStM, opEdH, opEdM, rcRoom + 1, rcStH, rcStM, rcEdH, rcEdM);
}

}