Untitled
unknown
plain_text
a year ago
9.3 kB
7
Indexable
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct Classmate { long long int power; long long int label; long long int rank; long long int *attackHistory; long long int *prefixSum; // 动态数组:前缀和 long long int historyCapacity; // 记录攻击历史的容量 long long int attackCount; bool needsRewardUpdate; // 是否需要更新奖励 struct Classmate *next; struct Classmate *previous; } Classmate; Classmate *head = NULL; Classmate* createClassmate() { Classmate *newClassmate = (Classmate*)malloc(sizeof(Classmate)); newClassmate->label = 0; newClassmate->rank = 0; newClassmate->power = 0; newClassmate->attackHistory = (long long int*)malloc(sizeof(long long int)); // 初始大小为1 newClassmate->prefixSum = (long long int*)malloc(sizeof(long long int)); newClassmate->attackCount = 0; newClassmate->historyCapacity = 1; // 初始容量为1 newClassmate->needsRewardUpdate = false; newClassmate->next = NULL; newClassmate->previous = NULL; return newClassmate; } void appendClassmate(Classmate *classmate) { if (head == NULL) { head = classmate; } else { Classmate *current = head; while (current->next != NULL) { current = current->next; } current->next = classmate; classmate->previous = current; } } void rewardPower() { Classmate *current = head; if(current == NULL) { return; } while (current != NULL) { current->needsRewardUpdate = true; // 标记为待更新 current = current->next; } } void updateRewardsIfNeeded(Classmate *classmate , long long int N) { if (classmate->needsRewardUpdate) { // 这里添加计算力量值的逻辑,例如: classmate->power += (N- classmate->rank); // 假设 N 是全局变量或以其他方式获得 classmate->needsRewardUpdate = false; } } void addAttackRecord(long long int attackerLabel , long long int N) { Classmate *attacker = head; if(attacker == NULL ){return ; } // 查找攻击者 while (attacker != NULL && attacker->label != attackerLabel) { attacker = attacker->next; } if (attacker == NULL || attacker->rank == 1) { return; // 没有找到攻击者或者攻击者已经是第一名 } Classmate *target = attacker->previous; if (target == NULL) { return; // 没有目标或者目标已经是最后一名 } if (attacker->attackCount == attacker->historyCapacity) { // 当数组满时,扩大数组大小 attacker->historyCapacity *= 2; // 容量加倍 attacker->attackHistory = (long long int*)realloc(attacker->attackHistory, sizeof(long long int) * attacker->historyCapacity); attacker->prefixSum = (long long int*)realloc(attacker->prefixSum, sizeof(long long int) * attacker->historyCapacity); } // 在交换排名前更新攻击者和目标的奖励 updateRewardsIfNeeded(attacker, N); updateRewardsIfNeeded(target , N); // 更新能量 int powerIncrease = 0; if (attacker->power != target->power) { powerIncrease = target->power - attacker->power; attacker->power = target->power; } // 更新攻击历史和前缀和 attacker->attackHistory[attacker->attackCount] = powerIncrease; attacker->prefixSum[attacker->attackCount] = (attacker->attackCount == 0) ? powerIncrease : attacker->prefixSum[attacker->attackCount - 1] + powerIncrease; attacker->attackCount++; // 交换排名 int tempRank = attacker->rank; attacker->rank = target->rank; target->rank = tempRank; // 交换节点位置 Classmate *prevTarget = target->previous; Classmate *attackerNext = attacker->next; if (prevTarget != NULL) { prevTarget->next = attacker; } else { head = attacker; // 更新头节点 } attacker->previous = prevTarget; target->next = attackerNext; if (attackerNext != NULL) { attackerNext->previous = target; } attacker->next = target; target->previous = attacker; // // 如果攻击者现在是第一名,则更新head指针 // if (attacker->rank == 1) { head = attacker; } } void queryPower(long long int qi , long long int N) { Classmate *current = head; if(current == NULL) { return; } while (current != NULL) { updateRewardsIfNeeded(current , N); // 确保力量值是最新的 if (current->power >= qi) { printf("%lld %lld\n", current->rank, current->label); return; // 找到符合条件的同学并输出 } current = current->next; } printf("0 0\n"); // 如果没有符合条件的同学 } // void queryPower(long long int qi , long long int N) { // Classmate *current = head; // if(current == NULL ){return ; } // while (current != NULL) { // updateRewardsIfNeeded(current , N); // 确保力量值是最新的 // if(current->power >= qi) { current = current->next; } // } // if (current != NULL && current->previous != NULL && current->previous->power >= qi) { // current = current->previous; // 向前移动一个节点以报告正确的同学 // printf("%lld %lld\n", current->rank, current->label); // } else { // printf("0 0\n"); // 如果没有符合条件的同学 // } // } void queryAttackHistory(long long int bi, long long int mi) { Classmate *current = head; if (current == NULL) { return; } while (current != NULL && current->label != bi) { current = current->next; } if (current == NULL) { return; } if (mi > current->attackCount) { mi = current->attackCount; } long long int startIdx = current->attackCount - mi; if (startIdx < 0) { startIdx = 0; } // 计算增加的总力量 long long int totalIncrease = 0; if (mi > 0) { long long int lastIdx = current->attackCount - 1; totalIncrease = current->prefixSum[lastIdx]; if (startIdx > 0) { totalIncrease -= current->prefixSum[startIdx - 1]; } } printf("%lld\n", totalIncrease); } // 比较两个Classmate指针的label int compareByLabel(const void *a, const void *b) { Classmate *classmateA = *(Classmate**)a; Classmate *classmateB = *(Classmate**)b; return classmateA->label - classmateB->label; } void printGameRecordByLabel(long long int N) { Classmate *current = head; Classmate *array[N]; // 存储Classmate指针的数组 long long int index = 0; // 填充数组 while (current != NULL) { array[index++] = current; current = current->next; } // 按label排序 qsort(array, N, sizeof(Classmate*), compareByLabel); // 按排序后的顺序打印每个同学的攻击历史 for (long long int i = 0; i < N; i++) { printf("%lld ", array[i]->attackCount); for (int j = 0; j < array[i]->attackCount; j++) { printf("%lld ", array[i]->attackHistory[j]); } printf("\n"); } } void freeClassmates() { Classmate *current = head; while (current != NULL) { Classmate *temp = current; current = current->next; free(temp->attackHistory); // 释放攻击历史数组 free(temp->prefixSum); free(temp); // 释放Classmate节点 } head = NULL; // 将头指针设为空,避免悬挂指针 } int main() { long long int Classmates_num, operation_nums, recent_attacks; // 读取同学数量 N 和操作数量 T scanf("%lld %lld %lld", &Classmates_num, &operation_nums,&recent_attacks); // 初始化同学信息 for (int i = 0; i < Classmates_num; ++i) { int power; scanf("%lld", &power); Classmate *player = createClassmate(); player->rank = i + 1; player->label = i+1; player->power = power; appendClassmate(player); } // 根据操作类型处理事件 for (long long int i = 0; i < operation_nums; ++i) { long long int operation_type; scanf("%lld", &operation_type); switch (operation_type) { case 1: { long long int attackerLabel; scanf("%lld", &attackerLabel); addAttackRecord(attackerLabel , Classmates_num); break; } case 2: rewardPower(); break; case 3: { long long int qi; scanf("%lld", &qi); queryPower(qi , Classmates_num); break; } case 4: { long long int bi, mi; scanf("%lld %lld", &bi, &mi); queryAttackHistory(bi, mi); break; } } } printf("\n"); printGameRecordByLabel(Classmates_num); // 清理资源 freeClassmates(); // ... return 0; }
Editor is loading...
Leave a Comment