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

#define MAX_PROCESS 5

typedef struct PCB {
    char name[10];
    int priority;      // 优先级（动态变化）
    int need_time;     // 需要运行时间（固定）
    int run_time;      // 已运行时间（动态变化）
    char state;        // 'W'就绪 / 'R'运行 / 'F'完成
    int finish_time;   // 完成时刻
    int turn_time;     // 周转时间
    float wturn_time;  // 带权周转时间
} PCB;

PCB pcb[MAX_PROCESS];
int process_num = 0;
int current_time = 0;  // 全局时间轴

// 1. 初始化进程（你截图里的输入：aa 0 5, bb 0 8, cc 1 10）
void initProcess() {
    // 进程aa
    strcpy(pcb[0].name, "aa");
    pcb[0].priority = 0;
    pcb[0].need_time = 5;
    pcb[0].run_time = 0;
    pcb[0].state = 'W';
    // 进程bb
    strcpy(pcb[1].name, "bb");
    pcb[1].priority = 0;
    pcb[1].need_time = 8;
    pcb[1].run_time = 0;
    pcb[1].state = 'W';
    // 进程cc
    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;
}

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

// 3. 显示当前所有进程状态
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);
    }
}

// 4. 调度主逻辑
void schedule() {
    int finished = 0;
    int current;

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

    while (finished < process_num) {
        current = findMaxPriority();
        if (current == -1) break; // 理论上不会发生

        // 进程开始运行
        pcb[current].state = 'R';
        printf("\n运行进程：%s\n", pcb[current].name);

        // 运行1个时间片
        pcb[current].run_time++;
        current_time++;

        // 判断是否运行完成
        if (pcb[current].run_time == pcb[current].need_time) {
            pcb[current].state = 'F';
            pcb[current].finish_time = current_time; // ✅ 关键：只有完成时才赋值
            finished++;
            printf("进程 %s 运行完毕！完成时刻：%d\n", pcb[current].name, current_time);
        } else {
            // 未完成：优先级减1，回到就绪队列
            pcb[current].priority--;
            pcb[current].state = 'W';
        }

        showProcess();
    }
    printf("\n===== 所有进程调度完成 =====\n");
}

// 5. 计算并输出周转时间
void calcTurnaround() {
    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);
}

int main() {
    initProcess();
    schedule();
    calcTurnaround();
    return 0;
}