十道题入门C++

1.输入与输出

本题要求根据火车的出发时间和达到时间,编写程序计算整个旅途所用的时间。

输入:

在一行中给出 2 个 4 位正整数,其间以空格分隔,分别表示火车的出发时间和到达时间。每个时间的格式为 2 位小时数(00-23)和 2 位分钟数(00- 59),假设出发和到达在同一天内。

输出:

在一行输出该旅途所用的时间,格式为“hh:mm”,其中 hh 为 2 位小时数、mm 为 2 位分钟数

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    // 读取出发和到达时间的小时和分钟
    int startHour, startMin, endHour, endMin;
    scanf("%2d%2d %2d%2d", &startHour, &startMin, &endHour, &endMin);

    // 计算总分钟数
    int startTotalMinutes = startHour * 60 + startMin;
    int endTotalMinutes = endHour * 60 + endMin;

    // 如果到达时间小于出发时间,则假设它是次日到达
    if (endTotalMinutes < startTotalMinutes) {
        endTotalMinutes += 24 * 60;
    }

    int durationMinutes = endTotalMinutes - startTotalMinutes;

    // 计算小时和分钟
    int hours = durationMinutes / 60;
    int minutes = durationMinutes % 60;

    // 输出结果
    cout << setw(2) << setfill('0') << hours << ":" << setw(2) << setfill('0') << minutes << endl;

    return 0;
}

2.循环分支与判断

从键盘输入任意正整数,判断该数是否是回文数。所谓回文数就是从左到右读这个数与从右到左读这个数是一样的。例如12321、1221都是回文数。

输入:
测试案例的个数n
第一个测试值
第二个测试值

第n个测试值

输出:
各个测试值是否是回文数,是,就输出Yes,不是,就输出No

#include <iostream>
#include <iomanip>
#include <vector>
std::string reverseString(const std::string &str) {
    int n = str.length();
    std::string reversedStr;
    reversedStr.reserve(n);  // 为逆序字符串预留空间
    for (int i = n - 1; i >= 0; --i) {
        reversedStr.push_back(str[i]);
    }
    return reversedStr;
}
int main(){
    std::cout<<"how many integers are you going to type in ?"<<std::endl;
    int n;
    scanf("%d",&n);
    std::vector<std::string> numbers;
    numbers.reserve(n);
    for(int i=0;i<n;++i){
        std::string temp;
        std::cout << "Enter number " << (i + 1) << ": ";
        std::cin >> temp;
        numbers.push_back(temp);
    }
    for (std::string num : numbers){
        if (num==reverseString(num)){
            std::cout<<"Yes"<<std::endl;
        }
        else{
            std::cout<<"No"<<std::endl;
        }
    }

}

3.函数的定义和使用

本题要求实现一个简单函数,能计算给定的年份和月份的天数。使得可以利用该函数,输出给定年份中每个月的天数,其中1、3、5、7.8、10、12月有31天,4、6、9、11月有30天,2月平年有28天,闰年有29天。要求定义并调用函数month_days(year,month),该函数返回year年month月的天数

输入:
年year

输出:
该年1~12月每个月的天数

#include <iostream>
#include <iomanip>
// 判断是否为闰年
bool isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 获取指定年份和月份的天数
int month_days(int year, int month) {
    switch (month) {
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
            return 31;
        case 4: case 6: case 9: case 11:
            return 30;
        case 2:
            return isLeapYear(year) ? 29 : 28;
        default:
            return 0; // 无效月份
    }
}
int main() {
    int year;
    std::cin >> year; // 输入年份
    // 输出该年份每个月的天数
    for (int month = 1; month <= 12; ++month) {
        std::cout << month_days(year, month) << " ";
    }
    return 0;
}

4.数组

给你一个整数数组nums,请你用冒泡排序将该数组升序排列。

示例 1:
输入: nums = [5,2,3,1]输出:[1,2,3,5]

示例 2:
输入: nums = [5,1,1,2,0,0]输出:[0,0,1,1,2,5]

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <algorithm>
// 函数来交换两个元素的值
void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}
// 冒泡排序函数
void bubbleSort(std::vector<int> &arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}
// 主函数
int main() {
    std::vector<int> arr;
    std::string input;
    std::getline(std::cin, input);
    input.erase(0,8);
    input.erase(remove(input.begin(), input.end(), ']'), input.end());
    std::stringstream ss(input);
    std::string item;

    while (getline(ss, item, ',')) {  // 使用逗号作为分隔符
        arr.push_back(stoi(item));    // 将分割后的字符串转换为整数并添加到向量中
    }

    bubbleSort(arr); // 调用冒泡排序函数

    std::cout << '[';
    for (size_t i = 0; i < arr.size(); ++i) {
        std::cout << arr[i];
        if (i < arr.size() - 1) {
            // 如果不是最后一个元素,则在后面添加逗号和空格
            std::cout << ", ";
        }
    }
    std::cout << ']';  
    return 0;
}

5.二维数组

方阵循环右移

题目描述:

本题要求编写程序,将给定nxn方阵中的每个元素循环在该行内右移m个位置。

输入:

第一行给出两个正整数m和n (1<=n<=6) 。接下来一共n行,每行n个整数,表示一个n阶的方阵

输出:

按照输入格式输出移动后的方阵: 即输出n行,每行n个整数,每个整数后输出一个空格。

#include <iostream>
#include <vector>

int main(){
    int m,n;
    std::cin>>m>>n;
    std::vector<std::vector<int>> matrix(n, std::vector<int>(n)), matrix1(n, std::vector<int>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            std::cin >> matrix[i][j]; 
        }
    }    
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int new_position = (j + m) % n;
            matrix1[i][new_position] = matrix[i][j];
        }
    }  
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            std::cout << matrix1[i][j]<<" "; 
        }
        std::cout<<std::endl;
    }
    return 0;
}

6.结构体

结构体
题目描述:
从键盘输入若干个学生的信息,每个学生信息包括学号、姓名、3门课的成绩,计算每个学生的总分,输出总分最高的学生的信息。

输入:
首先输入一个整数n(1<=n<=100),表示学生人数,然后输入n行,每行包含一个学生的信息: 学号(12位) 、姓名(不含空格且不超过20位),以及三个整数,表示语文、数学、英语三门课成绩,数据之间用空格隔开。

输出:
输出总成绩最高的学生的学号、姓名、及三门课成绩,用空格隔开。若有多个最高分,只输出第一个。

#include <iostream>
#include <vector>

struct Student{
    std::string name;
    int id;
    int score[3];
    int total;
};

int main(){
    int n;
    std::cin >> n;
    std::vector<Student> students(n);
    for (int i =0;i<n;++i){
        std::cin >> students[i].id >> students[i].name >> students[i].score[0] >> students[i].score[1] >> students[i].score[2];
        students[i].total = students[i].score[0] + students[i].score[1] + students[i].score[2];
    }
    int maxIndex = 0;
    for (int i = 1; i < n; ++i) {
        if (students[i].total > students[maxIndex].total) {
            maxIndex = i;
        }
    }
    
    std::cout << students[maxIndex].id << " "
              << students[maxIndex].name << " "
              << students[maxIndex].score[0] << " "
              << students[maxIndex].score[1] << " "
              << students[maxIndex].score[2] << std::endl;

    return 0;
}

7.指针

int n ;int *n ; int ** n 是什么意思?
在 C++ 中,指针是用于存储变量地址的变量。

  1. int n;:这是一个普通的整型变量 n 的声明,它可以存储一个整数值。
  2. int *n;:这是一个整型指针变量 n 的声明。它可以存储一个整数的地址,而不是整数本身。你可以使用这个指针来访问和修改它指向的整数。
  3. int **n;:这是一个指向整型指针的指针变量 n 的声明,也称为二级指针。它可以存储另一个整型指针的地址。这通常用于动态数组、动态二维数组,或者当你想要通过引用来修改一个指针时。

下面是每种声明的例子和它们的使用方法:

int n = 5; // 普通整型变量
int *ptr = &n; // 指针变量,存储变量n的地址
int **pptr = &ptr; // 二级指针变量,存储指针ptr的地址

在这个例子中:

  • n 存储了一个值 5

  • ptr 存储了 n 的地址,并可以用来间接访问 n(例如 *ptr 会给你 n 的值)。

  • pptr 存储了 ptr 的地址,并可以用来间接访问 ptr 本身(例如 *pptr 会给你 ptr 的值,而 **pptr 会给你 n 的值)。

8.了解函数传参的不同方式和变量作用域

试运行以下代码,分析为什么效果不同。

#include<iostream>
using namespace std;
void swap(int a,int b){//值传递
 int t=a;
 a = b;
 b= t;
}
void swap1(int *a,int *b){//传指针
 int t=*a;
 *a = *b;
 *b= t;
}
int main(){
 int a=2,b=3;
 swap(a,b);
 cout<<"a="<<a<<"b="<<b<<endl;
 a=2;b=3;
 swap1(&a,&b); 
 cout<<"a="<<a<<"b="<<b<<endl;
}

swap 函数使用值传递,它接收两个整数的拷贝,对这些拷贝进行交换。由于它们是拷贝,所以原始的 ab 的值不会被交换。

swap1 函数使用指针,它接收两个整数的地址,并通过指针直接在内存中交换它们的值。这样,原始的 ab 的值确实会被交换。

9.内存

介绍C++的内存分区情况。C++动态分配内存用什么方法?为什么需要这么做?用 new 关键字自定义长度的数组。

C++程序的内存分为几个部分,每部分用于存储不同类型的数据:

  1. 栈(Stack):由编译器自动分配释放,存放函数的参数值、局部变量等。其操作方式类似于数据结构中的栈。
  2. 堆(Heap):一般由程序员分配释放,若程序员不释放,则程序结束时可能由操作系统回收。用于动态内存分配。
  3. 全局/静态存储区(Global/Static Storage):存放全局变量和静态变量。
  4. 文字常量区:常量字符串就是放在这里的。程序结束后由系统释放。
  5. 程序代码区:存放函数体的二进制代码。

在C++中,动态内存分配是指在程序运行时(而非在编译时)分配内存。动态内存分配是必要的,因为有时候直到程序运行时我们才知道需要多少内存,例如用户输入数据的大小或者根据文件大小分配内存。

动态分配内存的方法:

在C++中,动态内存分配主要通过newdelete关键字来管理。

使用new关键字可以在堆上分配内存。当你使用new时,内存会从堆上分配,并且new会返回指向分配的内存的指针。当你不再需要这块内存时,你应该使用delete来释放它,防止内存泄漏。

例如,自定义长度的数组:

#include <iostream>

int main() {
    int size = 0;
    std::cout << "Enter the size of the array: ";
    std::cin >> size;

    int* myArray = new int[size]; // 动态分配数组

    // 使用数组...
    for (int i = 0; i < size; i++) {
        myArray[i] = i;
    }

    for (int i = 0; i < size; i++) {
        std::cout << myArray[i] << " ";
    }
    std::cout << std::endl;

    delete[] myArray; // 释放数组

    return 0;
}

在上面的例子中,new int[size]动态地在堆上分配了一个数组。这意味着我们可以在运行时决定数组的大小。然后我们使用delete[]来释放数组内存。

注意,动态分配的单个变量使用delete来释放,而动态分配的数组则需要使用delete[]来释放。

为什么需要动态分配内存:

  1. 灵活性:动态内存分配让程序可以根据实际需要分配内存,这在处理不确定大小的数据或大量数据时非常有用。
  2. 控制:它给程序员更多的控制权,可以精细地管理内存的生命周期。
  3. 生存期:动态分配的内存在堆上,它的生存期不受局部作用域的限制,可以在函数调用结束后继续存在,直到用delete释放。

正确管理动态分配的内存是非常重要的,因为不当管理会导致内存泄漏或者野指针等错误。现代C++推荐使用智能指针如std::unique_ptrstd::shared_ptr来自动管理内存,以避免这些问题。

10.指针与堆内存分配

动态矩阵
题目描述:
未知一个整数矩阵的大小,在程序运行时才会输入矩阵的行数m和列数n要求使用指针,结合new方法,动态创建一个二维数组,并求出该矩阵的最小值和最大值,可以使用数组下标法。不能先创建一个超大矩阵,然后只使用矩阵的一部分空间来进行数据访问、创建的矩阵大小必须和输入的行数m和列数n一样

输入:
第一行输入t表示t个测试实例
第二行输入两个数字m和n,表示第一个矩阵的行数和列数第三行起,连续输入m行,每行n个数字,表示输入第一个矩阵的数值依次输入t个实例

输出:
每行输出一个实例的最小值和最大值

#include <iostream>
#include <limits>
#include <vector>
int main() {
    int t;
    std::cin >> t; // 读取测试实例个数
    std::vector<std::pair<int, int>> values;

    while (t--) {
        int m, n;
        std::cin >> m >> n; // 读取矩阵大小

        // 动态创建二维数组
        int** matrix = new int*[m];
        for (int i = 0; i < m; ++i) {
            matrix[i] = new int[n];
        }

        // 读取数据并找到最小值和最大值
        int min_value = std::numeric_limits<int>::max();
        int max_value = std::numeric_limits<int>::min();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                std::cin >> matrix[i][j];
                if (matrix[i][j] < min_value) {
                    min_value = matrix[i][j];
                }
                if (matrix[i][j] > max_value) {
                    max_value = matrix[i][j];
                }
            }
        }
        values.push_back({min_value, max_value});

        // 删除二维数组
        for (int i = 0; i < m; ++i) {
            delete[] matrix[i];
        }
        delete[] matrix;
    }

    for (const auto& value : values) {
        std::cout << value.first << " " << value.second << std::endl;
    }

    return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值