#include <stdio.h>
#include <string.h>

#define MAX_PROCESS 5  // 最多5个进程

// 定义进程控制块PCB，新增周转时间相关字段
typedef struct PCB {
    char name[10];     // 进程名
    int priority;      // 优先级
    int need_time;     // 需要运行时间
    int run_time;      // 已运行时间
    char state;        // 状态：R-运行，W-就绪，F-完成
    int finish_time;   // 完成时刻（新增，用于计算周转时间）
    int turn_time;     // 周转时间（新增）
    float wturn_time;  // 带权周转时间（新增）
} PCB;

PCB pcb[MAX_PROCESS];  // 进程数组
int process_num = 0;   // 实际进程数
int current_time = 0;  // 全局时间，记录当前时刻（新增）

// 初始化进程（和你截图里的输入数据完全一致）
void initProcess() {
    // 输入数据：aa 0 5，bb 0 8，cc 1 10
    strcpy(pcb[0].name, "aa");
    pcb[0].priority = 0;
    pcb[0].need_time = 5;
    pcb[0].run_time = 0;
    pcb[0].state = 'W';

    strcpy(pcb[1].name, "bb");
    pcb[1].priority = 0;
    pcb[1].need_time = 8;
    pcb[1].run_time = 0;
    pcb[1].state = 'W';

    strcpy(pcb[2].name, "cc");
    pcb[2].priority = 1;
    pcb[2].need_time = 10;
    pcb[2].run_time = 0;
    pcb[2].state = 'W';

    process_num = 3;
    current_time = 0; // 初始时刻为0
}

// 查找当前优先级最高的就绪进程
int findMaxPriority() {
    int max = -1;
    int index = -1;
    for (int i = 0; i < process_num; i++) {
        if (pcb[i].state == 'W' && pcb[i].priority > max) {
            max = pcb[i].priority;
            index = i;
        }
    }
    return index;
}

// 显示所有进程信息
void showProcess() {
    printf("\n当前进程状态：\n");
    printf("进程名\t优先级\t需运行时间\t已运行时间\t状态\n");
    for (int i = 0; i < process_num; i++) {
        printf("%s\t%d\t%d\t\t%d\t\t%c\n",
               pcb[i].name, pcb[i].priority,
               pcb[i].need_time, pcb[i].run_time, pcb[i].state);
    }
}

// 输出最终的周转时间统计（新增）
void showTurnaroundInfo() {
    float total_turn = 0;
    float total_wturn = 0;
    printf("\n===== 进程调度完成，周转时间统计 =====\n");
    printf("进程名\t完成时刻\t周转时间\t带权周转时间\n");
    for (int i = 0; i < process_num; i++) {
        // 计算周转时间（假设所有进程同时到达，到达时刻为0）
        pcb[i].turn_time = pcb[i].finish_time - 0;
        pcb[i].wturn_time = (float)pcb[i].turn_time / pcb[i].need_time;
        total_turn += pcb[i].turn_time;
        total_wturn += pcb[i].wturn_time;
        printf("%s\t%d\t\t%d\t\t%.2f\n",
               pcb[i].name, pcb[i].finish_time,
               pcb[i].turn_time, pcb[i].wturn_time);
    }
    printf("平均周转时间：%.2f\n", total_turn / process_num);
    printf("平均带权周转时间：%.2f\n", total_wturn / process_num);
}

// 进程调度主函数
void scheduleProcess() {
    int finish_count = 0;  // 完成进程数
    int current;           // 当前运行进程下标

    printf("===== 最高优先数优先调度算法开始 =====\n");
    showProcess();

    while (finish_count < process_num) {
        current = findMaxPriority();
        if (current == -1) break;  // 无就绪进程

        // 选中进程运行
        pcb[current].state = 'R';
        printf("\n运行进程：%s\n", pcb[current].name);
        pcb[current].run_time++;   // 运行时间+1
        current_time++;            // 全局时间+1（新增）

        // 运行完成
        if (pcb[current].run_time == pcb[current].need_time) {
            pcb[current].state = 'F';
            pcb[current].finish_time = current_time; // 记录完成时刻（新增）
            finish_count++;
            printf("进程 %s 运行完毕！\n", pcb[current].name);
        } else {
            // 动态优先级：运行一次优先级-1
            pcb[current].priority--;
            pcb[current].state = 'W';
        }
        showProcess();
    }
    printf("\n===== 所有进程调度完成 =====\n");
    showTurnaroundInfo(); // 输出周转时间统计（新增）
}

int main() {
    initProcess();    // 初始化并输入进程
    scheduleProcess();// 调度进程
    return 0;
}