6207. 统计定界子数组的数目「多指针」

第315场周赛hard题,没有想出来,在此做记录,参考了三位大佬的题解:

  1. 灵佬的题解
  2. twilight的题解
  3. newhar的题解

思路

本题思路相当于把一个连续的数组分为若干个块,每个块外为[minK, maxk]范围外的数字,块内为范围内的数字,且包含有minKmaxK。以下图为例:
minK = 2maxK = 4

遍历nums,记录每个块中最后出现的maxK以及minK出现的位置下标lastMax以及lastMin
在每一个块内部,假设其起始坐标为0,且块内下标lastMax以及lastMin已经得到,则遇到下一个[minK, maxK]范围内的数时,以这个数下标为右边界,左边界可在[0, min(lastMax, lastMin)]中任意取得。即可得ans += min(lastMax, lastMin)

在遍历的时候,每个块的起始坐标不为0,可以额外维护一个变量outI,表示最后一个范围外的数的下标。若min(lastMax, lastMin) < outI,说明outI右侧maxKminK还没有全部出现,因此此时当前答案加0。

代码如下:

class Solution {
public:
    long long countSubarrays(vector<int>& nums, int minK, int maxK) {
        int lastMin = -1, lastMax = -1, outI = -1;
        long long ans = 0;
        
        for(int i=0; i< nums.size(); ++i){
            //枚举右边界
            if(nums[i] == minK){
                lastMin = i;
            }
            if(nums[i] == maxK){
                lastMax = i;
            }
            if(nums[i] < minK || nums[i] > maxK){
                outI = i;
            }
            ans += max(min(lastMin, lastMax) - outI, 0);
        }
        
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些思路。 首先,您需要定义一个结构体来存储学生信息,包括学号、姓名、三科成绩以及总分。例如: ``` struct student { char id[20]; char name[20]; float score1; float score2; float score3; float total_score; }; ``` 接下来,您可以定义一个指向文件的指针,并打开文件。例如: ``` FILE *fp; fp = fopen("d:\\xsxx.txt", "r+"); if (fp == NULL) { printf("文件打开失败!"); return 0; } ``` 然后,您可以使用循环来读取文件中的信息,并将其存储到结构体数组中。例如: ``` struct student xs[100]; int i = 0; while (!feof(fp)) { fscanf(fp, "%s %s %f %f %f", xs[i].id, xs[i].name, &xs[i].score1, &xs[i].score2, &xs[i].score3); xs[i].total_score = xs[i].score1 + xs[i].score2 + xs[i].score3; i++; } int n = i; // 学生数目为 n ``` 接下来,您可以从键盘输入一个学生的信息,并将其添加到结构体数组的末尾。例如: ``` struct student new_student; printf("请输入学生学号、姓名、三科成绩:"); scanf("%s %s %f %f %f", new_student.id, new_student.name, &new_student.score1, &new_student.score2, &new_student.score3); new_student.total_score = new_student.score1 + new_student.score2 + new_student.score3; xs[n] = new_student; n++; // 学生数目加一 ``` 然后,您可以使用指针法计算每个学生的总分,并显示每个学生的姓名和总分。例如: ``` for (int i = 0; i < n; i++) { struct student *p = &xs[i]; p->total_score = p->score1 + p->score2 + p->score3; printf("%s %.2f\n", p->name, p->total_score); } ``` 接下来,您可以统计最高总分和对应的学生姓名。例如: ``` float max_score = 0; char max_name[20]; for (int i = 0; i < n; i++) { if (xs[i].total_score > max_score) { max_score = xs[i].total_score; strcpy(max_name, xs[i].name); } } printf("最高总分为 %.2f,对应的学生姓名为 %s\n", max_score, max_name); ``` 然后,您可以按总分从小到大排序,并输出学号、姓名和总分。例如: ``` for (int i = 0; i < n-1; i++) { for (int j = i+1; j < n; j++) { if (xs[i].total_score > xs[j].total_score) { struct student temp = xs[i]; xs[i] = xs[j]; xs[j] = temp; } } } printf("学号\t姓名\t总分\n"); for (int i = 0; i < n; i++) { printf("%s\t%s\t%.2f\n", xs[i].id, xs[i].name, xs[i].total_score); } ``` 最后,您需要将这次运行添加的学生信息也写入文件中。例如: ``` for (int i = n-1; i < n; i++) { fprintf(fp, "%s %s %.2f %.2f %.2f\n", xs[i].id, xs[i].name, xs[i].score1, xs[i].score2, xs[i].score3); } fclose(fp); ``` 以上是一个简单的思路,您可以根据实际需求进行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值