21级青藤工作室第一次考核答案

21级青藤工作室第一次考核答案

一、

一个小球距地面 10 米处垂直落下,当小球触底反弹时,由于受到神秘力量 影响,小球的初速度瞬间增大,使得每次反弹的高度都为原高度的 2 倍。请编 写一个函数,在误差合理范围内求前 n 次反弹时向上的初速度(分别输出每一 次的速度)。可使用 sqrt 函数 。不计空气阻力,g 取 10m/s^2 (0 < n < 101 ),n 为整数。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double MagicBall(int n);

int main()
{
    int n;
    scanf("%d", &n);

    for (int i = 1; i <= n; i++)
    {
        printf("小球第 %d 次反弹时的速度为:%lf\n", i, MagicBall(i));

    }
    system("pause");
    return 0;

}

double MagicBall(int n)
{
    double hight = 10; //小球高度
    int count = n; //小球要反弹的次数
    while (n)
    {
        hight *= 2.0; //计算第 n 次反弹结束时小球距离地面的高度
        n--;
    }
    double t = sqrt(2 * hight / 10 );  // 1/2 * g * t^2  = s 求 t
    double v = 10 * t; // v= g*t
    return v;
    
}

二、

二、给你一个字符串 num ,表示一个大整数。请你在字符串 num 的所有 非空 子字符串 中找出 值最大的奇数 ,并以字符串形式返回。如果不存在奇数,则 返回一个空字符串 “” 。 子字符串 是字符串中的一个连续的字符序列

  • 示例 1:
  • 输入:num = “52”
  • 输出:“5”
  • 解释:非空子字符串仅有 “5”、“2” 和 “52” 。 “5” 是其中唯一的奇数。
  • 示例 2:
  • 输入:num = “4206”
  • 输出:""
  • 解释:在 “4206” 中不存在奇数。
  • 示例 3:
  • 输入:num = “35427”
  • 输出:“35427”
  • 解释:“35427” 本身就是一个奇数。
#include <stdio.h>
#include <stdbool.h>

#define MAX_STR_LEN 64

int read_line(char *dest, int sz);

int main() {
    char inp[MAX_STR_LEN];
    printf("Tip: Enter empty line to quit.\n");
    char dest[MAX_STR_LEN];
    printf(">");
    int len = read_line(dest, MAX_STR_LEN);
    while (dest[0] != '\0') {
        bool proceed = false;
        for (int i = len - 1; i >= 0; --i) {
            if (dest[i] == '1' || dest[i] == '3' || dest[i] == '5' || dest[i] == '7' || dest[i] == '9') {
                proceed = true;
                dest[i + 1] = '\0';
                printf("%s", dest);
                break;
            }
        }
        if (!proceed) {
            printf("(EMPTY)");
        }
        printf("\n");

        printf(">");
        len = read_line(dest, MAX_STR_LEN);
    }

    return 0;
}

int read_line(char *dest, int sz) {
    int pos = 0;
    char c = getchar();
    while (c != '\n' && c != '\0') {
        if (pos < sz - 1) {
            dest[pos] = c;
            pos++;
        }
        c = getchar();
    }
    dest[pos] = '\0';
    return pos;
}

三、

三、给定一个字符串,请写一个程序,将该字符串中的空格全部删除。
*提示: C 语言中的字符串是 char 数组,字符串的结尾为’\0’(该字符不计入字 符串)。

  • 你能不创建额外的字符串数组,原地对字符串进行修改吗?
  • 示例: 输入:I am a boy
  • 输出: Iamaboy
#include <stdio.h>
#include <stdlib.h>

// 程序中容许从用户输入接收的字符串的最大长度
#define MAX_STR_LEN 64

void read_line(char *dest, int sz);
void do_erase_spaces(char dest[]);

int main() {
    printf("Tip: Enter empty line to quit.\n");
    char dest[MAX_STR_LEN];             // 这个数组用于接收用户输入以及对字符串进行处理
    printf(">");
    read_line(dest, MAX_STR_LEN);       // 读取用户输入的一行字符串,while中的read_line同理
    while (dest[0] != '\0') {           // 只要输入的字符串不为空就做处理
        do_erase_spaces(dest);          // 移除字符串的空格
        printf("%s\n", dest);           // 打印字符串
        printf(">");
        read_line(dest, MAX_STR_LEN);   // 继续读取输入的字符串
    }
    return 0;
}

// 移除字符串空格的的函数,dest为传入的字符串数组
void do_erase_spaces(char dest[]) {
    // 这个算法使用双指针的思想,字符串中的每个字符只扫描一遍
    // 扫描的当前位置用下面for循环的scan表示,下一个字符串赋值位置用cpy表示。
    // 当扫描字符串时,若当前字符不是空格则需要将当前字符赋值到dest[cpy],并对cpy加1。
    // cpy的初始值为0,即代表字符串数组的第一个元素。
    // 实际情况下这段代码一定满足cpy<=scan,即对dest[cpy]赋值不会影响到字符串后续位置的扫描。
    int cpy = 0;  
    for (int scan = 0; dest[scan] != '\0'; ++scan) {    // 对整个字符串进行扫描
        if (dest[scan] != ' ') {                        // 如果当前字符串不是空格
            // 将当前字符复制到dest[cpy],并cpy++,等效于删除空格
            dest[cpy] = dest[scan];
            cpy++;
        }
    }
    // 循环结束之后cpy代表的数组位置一定会是删除空格后的字符串结尾后一位
    // 需要将该位置的数组元素赋值为\0代表字符串结尾,这是C语言字符串的一个规定。
    dest[cpy] = '\0';
}

// 读取用户输入的一行字符串,这个函数的实现原理不在本题的讨论范围之内。
void read_line(char *dest, int sz) {
    int pos = 0;
    char c = getchar();
    while (c != '\n' && c != '\0') {
        if (pos < sz - 1) {
            dest[pos] = c;
            pos++;
        }
        c = getchar();
    }
    dest[pos] = '\0';
}

四、

这里有一个石头堆为 s,它由宝石 ‘a’ 和石头 ‘b’ 组成。清理工明明要将 这堆石头清理走,以知明明每一次清理都可以从 s 中删除一个回文子序列。 求返回拿走给定石头堆中所有宝石和石头(字符串为空)的最小清理次数。
「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字 符顺序得到,那么这个字符串就是原字符串的一个子序列。
「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一 个回文。

  • 示例:
  • 输入:s = “ababa”
  • 输出:1
  • 解释:字符串本身就是回文序列,只需要删除一次。
  • 输入:s = “abb”
  • 输出:2
  • 解释:“abb” -> “bb” -> “”. 先删除回文子序列 “a”,然后再删除 “bb”。
#include<stdio.h>
//思路:
//回文子序列不是回文子字符串,比如"aababdaba","aaaaa"就是他的回文子序列。
//也就是顶多删两次,一次全删掉"a",一次全删掉"b"。
//如果是回文字符串,就删一次。
//空字符串就0次。

int MyStrlen(char *src)//求字符串长度的函数,也可以加#include<string.h>头文件,直接使用strlen函数
{
    int len = 0;
    while(src[len])
    {
        len++;
    }
    return len;
}

int removePalindromeSub(char * str){
    int length = MyStrlen(str);
    if(length == 0)
    return 0;
    int low = 0, high = length - 1;
    while(low < high)//若该循环完美执行完那么该字符串恰好就是一个回文串
    {
        if(str[low] != str[high])
        return 2;//不符合回文串的定义就必须删除2次
        low++;
        high--;
    }
    return 1;//恰好是回文串就能1次删除成功
}

int main(){
    char str[10];  //str是string的缩写, 即字符串
    printf("请输入字符串:");
    scanf("%s", str);
    /*输入参数是已经定义好的“字符数组名”,
    不用加&, 因为在C语言中数组名就代表该数组的起始地址*/
    int i = removePalindromeSub(str);
    printf("%d",i);
    return 0;
}

五、

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的 三个整数,使得它们的和与 target 最不接近。返回这三个数的和。假定每组输 入只存在唯一答案。 例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最不接近的三个数的和为 -3 (-1+1-4=-4)

  • 难点:三次去重
  • 思路:
    1.给数组排序
    2.遍历数组,从0遍历到 numsize - 2
    3.如果当前的数字等于前一个数字,则跳过这个数
    4.如果数字不同,则设置left = i +1 , right = numsize -1 ,查看i ,left, right三个数的和sum,取与target的差值最大的,比较sum比target大还是小,如果比target小,start++,如果比target大,end–
    5.返回结果

双指针解法:

#include<stdio.h>
#include<math.h>
void quickSort(int* nums, int first, int end) {                    //快速排序
    int temp, l, r;
    if (first >= end) {
        return;
    }
    temp = nums[first];
    l = first;
    r = end;
    while (l < r) {
        while (l < r && nums[r] >= temp) {
            r--;
        }
        if (l < r) {
            nums[l] = nums[r];
        }
        while (l < r && nums[l] <= temp) {
            l++;
        }
        if (l < r) {
            nums[r] = nums[l];
        }
    }
    nums[l] = temp;
    quickSort(nums, first, l - 1);
    quickSort(nums, l + 1, end);
}

int threeSumClosest(int* nums, int numsSize, int target) {
    int i = 0;                                                    //当前数值下标
    int res = nums[0] + nums[1] + nums[2];                        //和,初始化

    if (numsSize < 3 || nums == NULL) {
        return NULL;
    }

    quickSort(nums, 0, numsSize - 1);                           //排序

    for (i = 0; i <= numsSize - 3; i++) {
        int left = i + 1;                                        //左指针
        int right = numsSize - 1;                                //右指针
        if (i > 0 && nums[i] == nums[i - 1]) {                    //去重
            continue;
        }
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (abs(sum - target) > abs(res - target)) {        //取最不接近的和
                res = sum;
            }
            if (sum < target) {
                while (left < right && nums[right] == nums[right - 1]) {
                    right--;
                }
                right--;
            }
            else if (sum > target) {
                while (left < right && nums[left] == nums[left + 1]) {
                    left++;
                }
                left++;
            }
            else {
                return sum;
            }
        }
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值