赞
踩
6.输入一个非递减排列的整数数组nums,和一个目标值target。请找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值target,则输出0,0。请设计一个时间复杂度为0(log n)的算法解决此问题。
输入包括两行,第一行输入两个整数,分别表示数组的长度和target,第二行输入数组nums。输出为一个整数。
例如输入:
6 8
5 7 7 8 8 10
则输出: 4 5
若输入:
6 9
5 7 7 8 8 10
则输出: 0 0
- #include <stdio.h>
-
- // 二分查找的变种,用于找到目标值的左边界
- int findLeftBound(int* nums, int numsSize, int target) {
- int left = 0, right = numsSize - 1;
- int leftBound = -1; // 初始化左边界为-1,表示未找到
- while (left <= right) {
- int mid = left + (right - left) / 2;
- if (nums[mid] >= target) {
- right = mid - 1; // 尝试在左半部分查找
- leftBound = mid; // 更新左边界
- } else {
- left = mid + 1;
- }
- }
- return leftBound;
- }
-
- // 二分查找的变种,用于找到目标值的右边界
- int findRightBound(int* nums, int numsSize, int target) {
- int left = 0, right = numsSize - 1;
- int rightBound = -1; // 初始化右边界为-1,表示未找到
- while (left <= right) {
- int mid = left + (right - left) / 2;
- if (nums[mid] <= target) {
- left = mid + 1; // 尝试在右半部分查找
- rightBound = mid; // 更新右边界
- } else {
- right = mid - 1;
- }
- }
- return rightBound;
- }
-
- int main() {
- int numsSize, target;
- scanf("%d %d", &numsSize, &target);
- int nums[numsSize];
- for (int i = 0; i < numsSize; i++) {
- scanf("%d", &nums[i]);
- }
-
- int leftBound = findLeftBound(nums, numsSize, target);
- int rightBound = findRightBound(nums, numsSize, target);
-
- // 如果左边界仍为-1,说明未找到目标值
- if (leftBound == -1) {
- printf("0 0\n");
- } else {
- printf("%d %d\n", leftBound + 1, rightBound + 1); // 数组索引从0开始,输出从1开始
- }
-
- return 0;
- }
函数
findStartIndex
:
- 使用修改版的二分查找来找到目标值在数组中的起始位置。
- 初始化左右边界,然后在循环中根据中间元素与目标值的比较调整左右边界。
- 如果找到目标值,更新
start
并继续向左查找。函数
findEndIndex
:
- 使用同样的修改版二分查找来找到目标值在数组中的结束位置。
- 初始化左右边界,然后在循环中根据中间元素与目标值的比较调整左右边界。
- 如果找到目标值,更新
end
并继续向右查找。主函数
main
:
- 输入数组的长度和目标值。
- 输入排序后的整数数组。
- 调用
findStartIndex
和findEndIndex
函数找到目标值的起始位置和结束位置。- 如果找到了起始位置和结束位置,则输出它们;否则输出 "0 0" 表示目标值不存在于数组中。
7. 残缺棋盘是一个有2k×2k (k≥1)个方格的棋盘,其中恰有一个方格残缺。 下图给出k=1时各种可能的残缺棋盘,其中残缺的方格用阴影表示。
图中的棋盘称作“三格板”,残缺棋盘问题就是用这四种三格板覆盖更大的残缺棋盘。在覆盖中要求: 1)两个三格板不能重叠 2)三格板不能覆盖残缺方格,但必须覆盖其他所有方格 编程输入k及残缺格的坐标,求残缺棋盘覆盖方法。 输入:三个整数,分别表示k值和残缺格的坐标; 输出:2k×2k矩阵,具体数值为覆盖的序号。
- #include<stdio.h>
- #include<math.h>
- void TileBoard(int tr,int tc,int dr,int dc,int size);
- void OutputBoard(int size);
- int tile=1;
- int Board[1025][1025];
- int main()
- {
- int n,a,b;
- scanf("%d",&n);
- int sum;
- sum=pow(2,n);
- scanf("%d %d",&a,&b);
- Board[n][n]=0;
- TileBoard(0,0,a,b,sum);
- OutputBoard(sum);
- return 0;
- }
- void TileBoard(int tr,int tc,int dr,int dc,int size)
- {
- if(size==1) return;
- int t=tile++,
- s=size/2;
- if(dr<tr+s&&dc<tc+s)
- TileBoard(tr,tc,dr,dc,s);
- else
- {
- Board[tr+s-1][tc+s-1]=t;
- TileBoard(tr,tc,tr+s-1,tc+s-1,s);
- }
- if(dr<tr+s&&dc>=tc+s)
- TileBoard(tr,tc+s,dr,dc,s);
- else
- {
- Board[tr+s-1][tc+s]=t;
- TileBoard(tr,tc+s,tr+s-1,tc+s,s);
- }
- if(dr>=tr+s&&dc<tc+s)
- TileBoard(tr+s,tc,dr,dc,s);
- else
- {
- Board[tr+s][tc+s-1]=t;
- TileBoard(tr+s,tc,tr+s,tc+s-1,s);
- }
- if(dr>=tr+s&&dc>=tc+s)
- TileBoard(tr+s,tc+s,dr,dc,s);
- else
- {
- Board[tr+s][tc+s]=t;
- TileBoard(tr+s,tc+s,tr+s,tc+s,s);
- }
- }
- void OutputBoard(int size)
- {
- for(int i=0;i<size;i++)
- {
- for(int j=0;j<size;j++){
- printf("%-3d",Board[i][j]);
- }
- printf("\n");
- }
- printf("end");
- }
8. 活动安排问题求解: 假设某社团某一天要组织n个活动E={1,2,3...n},其中每个活动都要求使用同一礼堂,而且在同一时间内只有一个活动能使用这个礼堂。每个活动i都有一个要求使用礼堂的起始时间si和结束时间fi, 且有si<fi,。若区间(si,fi,)和(sj,fj,)不相交,则称活动i与活动j是相容的。
现在给定n个活动的开始时间和结束时间,请设计一个活动安排方案,使得安排的相容活动数目最多。
表1 活动时间表
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 |
1 | 2 | 0 | 5 | 3 | 5 | 6 | 8 | 2 | 12 | 15 |
3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 18 |
- #include <stdio.h>
- #include <stdlib.h>
-
- // 定义活动结构体,包含活动的索引、开始时间和结束时间
- struct Activity {
- int index; // 活动的索引或编号
- int start; // 活动的开始时间
- int end; // 活动的结束时间
- };
-
- // 比较函数,用于qsort,根据活动的结束时间进行排序
- // 返回值小于0表示a小于b,大于0表示a大于b,等于0表示a等于b
- int compare(const void *a, const void *b) {
- struct Activity *activityA = (struct Activity *)a; // 将void指针转换为Activity指针
- struct Activity *activityB = (struct Activity *)b; // 将void指针转换为Activity指针
- return (activityA->end - activityB->end); // 返回两个活动结束时间的差值
- }
-
- int main() {
- int n = 12; // 活动的总数
-
- // 初始化活动数组
- struct Activity activities[] = {
- {1, 1, 3},
- {2, 12, 14},
- {3, 0, 5},
- {4, 5, 7},
- {5, 6, 10},
- {6, 3, 8},
- {7, 8, 12},
- {8, 5, 9},
- {9, 8, 11},
- {10, 2, 13},
- {11, 2, 4},
- {12, 15, 18}
- };
-
- // 使用qsort函数对活动数组进行排序,根据活动的结束时间
- qsort(activities, n, sizeof(struct Activity), compare);
-
- // 初始化计数器,用于记录被安排的活动数量
- int counter = 1; // 至少可以安排一个活动
-
- // 初始化最后一个已安排活动的结束时间
- int last_end_time = activities[0].end; // 第一个活动的结束时间
-
- // 打印第一个被安排的活动
- printf("第%d个活动被安排: %d开始, %d结束.\n", activities[0].index, activities[0].start, activities[0].end);
-
- // 遍历剩余的活动,尝试安排它们
- for (int i = 1; i < n; i++) {
- // 如果当前活动的开始时间不小于上一个已安排活动的结束时间,则可以安排
- if (activities[i].start >= last_end_time) {
- counter++; // 增加计数器
- printf("第%d个活动被安排: %d开始, %d结束.\n", activities[i].index, activities[i].start, activities[i].end);
-
- // 更新最后一个已安排活动的结束时间
- last_end_time = activities[i].end;
- }
- }
-
- // 打印总计被安排的活动数量
- printf("总计%d个活动被安排\n", counter);
-
- return 0;
- }
9. 设有n个独立的作业{1,2…,n},由m台相同的机器进行加工处理。作业i所需时间为Ti。约定任何作业可以在任何一台机器上加工处理,但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。输入第一行输入n和m;第二行输入n个整数,分别表示n个作业做需要的时间,输出结果为一个整数,表示完成任务的最短时间。
- #include <stdio.h>
- #include <stdlib.h>
-
- // 比较函数,用于排序作业
- int compare(const void *a, const void *b) {
- return (*(int*)b - *(int*)a);
- }
-
- // 计算完成任务的最短时间
- int shortestCompletionTime(int n, int m, int jobs[]) {
- // 按处理时间从大到小排序作业
- qsort(jobs, n, sizeof(int), compare);
-
- // 初始化每台机器的当前总处理时间为0
- int machines[m];
- for (int i = 0; i < m; i++) {
- machines[i] = 0;
- }
-
- // 将作业分配给机器
- for (int i = 0; i < n; i++) {
- // 找到当前处理时间最短的机器
- int minIndex = 0;
- for (int j = 1; j < m; j++) {
- if (machines[j] < machines[minIndex]) {
- minIndex = j;
- }
- }
- // 分配作业给当前处理时间最短的机器,并更新其总处理时间
- machines[minIndex] += jobs[i];
- }
-
- // 找到所有机器中总处理时间最长的时间
- int maxTime = machines[0];
- for (int i = 1; i < m; i++) {
- if (machines[i] > maxTime) {
- maxTime = machines[i];
- }
- }
-
- return maxTime;
- }
-
- int main() {
- int n, m;
- scanf("%d %d", &n, &m);
-
- int jobs[n];
- for (int i = 0; i < n; i++) {
- scanf("%d", &jobs[i]);
- }
-
- // 计算并输出完成任务的最短时间
- int shortestTime = shortestCompletionTime(n, m, jobs);
- printf("%d", shortestTime);
- return 0;
- }
10. n个孩子站成一排。输入一个整数数组 ratings 表示每个孩子的评分。你需要按照以下要求,给这些孩子分发苹果:每个孩子至少分配到1个苹果。相邻两个孩子评分更高的孩子会获得更多的苹果。请你给每个孩子分发苹果,计算并返回需要准备的最少苹果数目。
- #include <stdio.h>
-
- int minApples(int ratings[], int n) {
- if (n <= 0) return 0;
- int apples[n];
- for (int i = 0; i < n; ++i) apples[i] = 1; // 每个孩子至少分配一个苹果
-
- // 从左向右扫描,保证右边评分高的孩子拿到的苹果比左边多
- for (int i = 1; i < n; ++i) {
- if (ratings[i] > ratings[i - 1]) {
- apples[i] = apples[i - 1] + 1;
- }
- }
-
- // 从右向左扫描,保证左边评分高的孩子拿到的苹果比右边多
- for (int i = n - 2; i >= 0; --i) {
- if (ratings[i] > ratings[i + 1] && apples[i] <= apples[i + 1]) {
- apples[i] = apples[i + 1] + 1;
- }
- }
-
- int totalApples = 0;
- for (int i = 0; i < n; ++i) {
- totalApples += apples[i];
- }
-
- return totalApples;
- }
-
- int main() {
- int n;
- scanf("%d", &n);
- int ratings[n];
- for (int i = 0; i < n; ++i) {
- scanf("%d", &ratings[i]);
- }
-
- int minTotalApples = minApples(ratings, n);
- printf("%d", minTotalApples);
-
- return 0;
- }
结语
宝剑锋从磨砺出
梅花香自苦寒来
!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。