简单的小题集(三)


一、逆序数的计算

逆序数(Inversion)是指在一个序列中,如果两个元素的顺序与它们在原序列中的顺序相反,
即前面的元素大于后面的元素,则这两个元素构成一个逆序数。逆序数反映了序列的无序程
度,逆序数越多,序列的无序程度越高。

#include <iostream>
#include <vector>
using namespace std;
// 归并排序函数,用于排序并计算逆序数
long long mergeSort(vector<int>& nums, int left, int right) {
 if (left >= right)
 return 0;
 int mid = left + (right - left) / 2;
 long long inversions = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);
 // 合并两个有序子数组
 int i = left, j = mid + 1;
 vector<int> sorted;
 while (i <= mid && j <= right) {
 if (nums[i] <= nums[j]) {
 sorted.push_back(nums[i]);
 i++;
 } else {
 sorted.push_back(nums[j]);
 j++;
 inversions += mid - i + 1; // 计算逆序数
 }
 }
 while (i <= mid) {
 sorted.push_back(nums[i]);
 i++;
 }
 while (j <= right) {
 sorted.push_back(nums[j]);
 j++;
 }
 // 将排序后的结果复制回原数组
 for (int k = left; k <= right; k++) {
 nums[k] = sorted[k - left];
 }
 return inversions;
}
// 计算逆序数的函数
long long countInversions(vector<int>& nums) {
 return mergeSort(nums, 0, nums.size() - 1);
}
int main() {
 int n;
 cout << "Enter the length of the sequence: ";
 cin >> n;
 vector<int> nums(n);
 cout << "Enter the sequence: ";
 for (int i = 0; i < n; i++) {
 cin >> nums[i];
 }
 long long inversions = countInversions(nums);
 cout << "Number of inversions: " << inversions << endl;
 return 0;
}

在上述代码中,使用归并排序的思想来计算逆序数。首先,定义了一个归并排序的函数
mergeSort,该函数接受一个整数向量 nums,以及待排序区间的左右边界 left 和 right。在
mergeSort 函数中,首先递归地将待排序的区间分成两半,然后分别对左右两个子区间进行
归并排序。在合并两个有序子数组的过程中,同时计算逆序数。当左子数组中的一个元素大
于右子数组中的一个元素时,将逆序数增加 mid - i + 1,其中 mid 是左子数组的最后一个
元素的下标,i 是左子数组的当前元素的下标。
接下来,定义了一个计算逆序数的函数 countInversions,该函数接受一个整数向量 nums。
在这个函数中,调用 mergeSort 函数来计算逆序数,并返回结果。
在 main 函数中,首先读取输入的序列的长度 n,然后读取序列的元素。接下来,调用
countInversions 函数计算逆序数,并输出结果

二、QHU 高数&线代&概率论

最近小浪爱上了高数&线代&概率论,今天中午放学时他的老师给了他一个[a,b]的区间,然后
说:首先你要将[a,b]种所有的数全部转化成“十六进制”,别急,还有要把这些数按顺序(比
如说[10,12],按顺序连起来就是 ABC,[20,22]按顺序连起来就是 141516)连起来,将连起来的
数再转化成“十进制”,最后将最终结果对 15 取模。

#include <stdio.h>
// 将一个十进制数转换为十六进制字符串
void decToHex(int dec, char hex[]) {
 sprintf(hex, "%X", dec);
}
// 将一个区间内的数按顺序连接并转换为十进制
int concatenateAndConvertToDec(int a, int b) {
 char hex[100]; // 用于存储十六进制字符串
 char concatenatedHex[100]; // 用于存储连接后的十六进制字符串
 int index = 0; // 连接后的十六进制字符串的索引
 for (int i = a; i <= b; i++) {
 decToHex(i, hex); // 将当前数转换为十六进制
 int j = 0;
 while (hex[j] != '\0') {
 concatenatedHex[index++] = hex[j++]; // 连接十六进制字符串
 }
 }
 concatenatedHex[index] = '\0'; // 添加字符串结束符
 int dec = strtol(concatenatedHex, NULL, 16); // 将连接后的十六进制字符串转换为十进return dec;
}
int main() {
 int a, b;
 printf("请输入区间的起始值 a:");
 scanf("%d", &a);
 printf("请输入区间的结束值 b:");
 scanf("%d", &b);
 int result = concatenateAndConvertToDec(a, b);
 int mod = result % 15;
 printf("最终结果对 15 取模的值为:%d\n", mod);
 return 0;
}

三、QHU 军训有射击

QHU 军训又开始了,但是这次不一样,教官增加了射击这一项目,小南想这是我第一次射
击打靶,心里十分开心,但是教官说完话,才知道只是个游戏,唉,但是回答正确的人可以
少站 1 小时的军姿,哇,这简直太爽了,那就请看题吧:
教官面前有一群高度不一的敌人,他手里拿着一把能削减敌人高度的枪,我们称为“QHU 神
枪”,这把“QHU 神枪”射出的子弹会在敌人间跳跃,一发子弹就能对所有敌人的高度减少 2,
如果该子弹导致了任意敌人高度小于等于 0,该子弹还会再次让所有敌人的高度减少 2,直
到没有新的敌人高度小于等于 0 为止。
那么,教官使用“QHU 神枪”要打出几颗子弹才能使所有敌人的高度都小于等于 0 呢?

#include <stdio.h>
#include <stdlib.h>
int calculateBullets(int height[], int numEnemies) {
 int bullets = 0;
 int i;
 while (1) {
 int negativeHeight = 0;
 // 射击过程
 for (i = 0; i < numEnemies; i++) {
 if (height[i] > 0) {
 height[i] -= 2;
 if (height[i] <= 0) {
 negativeHeight++;
 }
 }
 }
 // 检查是否还有新的敌人高度小于等于 0
 if (negativeHeight == 0) {
 break;
 }
 // 如果有新的敌人高度小于等于 0,则再次让所有敌人的高度减少 2
 bullets++;
 }
 return bullets;
}
int main() {
 int numEnemies;
 printf("请输入敌人的数量:");
 scanf("%d", &numEnemies);
 if (numEnemies <= 0) {
 printf("敌人数量必须大于 0。\n");
 return 0;
 }
 int* height = (int*)malloc(numEnemies * sizeof(int));
 int i;
 for (i = 0; i < numEnemies; i++) {
 printf("请输入第%d 个敌人的初始高度:", i + 1);
 scanf("%d", &height[i]);
 }
 int bullets = calculateBullets(height, numEnemies);
 printf("需要的子弹数量为:%d\n", bullets);
 free(height);
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Magic171

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值