高级语言程序设计(2024)

2024春期末题型回忆

  • 选择:是否关键字(volatile,operator, vector),结构体占用内存(一个结构体嵌套另一个结构体),友元关系性质,构造函数性质,变量初始化(指针,数组,引用),数组访问方式(指针),拷贝构造函数性质
  • 填空与简答:整型与浮点型进行运算的结果(int a = 3, c =2;float b = 3.0;求a/c,b/c);do while的输出;子类构造函数的输出
  • 编程题:Mystring类的实现(默认构造;逆序输出;析构函数);汽车类和子类的实现(拷贝构造为深拷贝),具体属性函数的实现

个人复习用

目录

 模版

题目描述

样例输入输出

代码 

 模板:任意基本类型的数相加

题目描述

样例输入输出

代码

虚函数:测试虚函数表

题目描述

样例输入输出

代码

虚函数:不同动物的吼声

题目描述

样例输入输出

代码

虚函数:计算几何图形的面积和周长

题目描述

样例输入输出

 代码

 学生类的定义

题目描述

样例输入输出

代码 

矩形重叠部分面积计算

题目描述

输入格式

输出格式

样例输入输出

代码

点和直线的关系

题目描述

输入描述

输出描述

样例输入输出

代码

逃离星球计划

题目描述

样例输入输出

代码

面向对象的Tensor

题目描述

样例输入输出

代码

实现Tensor的简单计算

题目描述

样例输入输出

代码

友元-输出两坐标点之间的距离

题目描述

样例输入输出

 代码

类的定义

题目描述

样例输入输出

代码

计算矩阵的行列式

题目描述

样例输入输出

代码

生成随机的Tensor张量

题目描述

样例输入输出

代码

链表:删除链表的倒数第 n 个结点

题目描述

样例输入输出

代码

重载运算符练习

题目描述

样例输入输出

代码

运算符重载:复数类的运算

题目描述

样例输入输出

代码

 运算符重载:坐标运算

题目描述

样例输入输出

代码

 函数:时间制度转换

题目描述

样例输入输出

代码

函数:计算x的y次幂

题目描述

样例输入输出

 代码

角谷猜想

题目描述

样例输入输出

代码

函数:计算兔子数量

题目描述

样例输入输出

代码

计算h指数

题目描述

样例输入输出

代码

按频率排序字符串

题目描述

样例输入输出

 代码

相邻元素最大距离

题目描述

样例输入输出

代码

 数组合并

题目描述

样例输入输出

代码

 鸡兔同笼问题

题目描述

样例输入输出

代码

消失的数字

题目描述

样例输入输出

代码

实现智能指针类

样例输入输出

代码

标准类库:实现智能指针2

样例输入输出

代码

链表:压缩的字符串表示

题目描述

样例输入输出

 代码

交换礼物

题目描述

样例输入输出

 代码

浮点数组排序

题目描述

样例输入输出

代码 

数组排序

题目描述

样例输入输出

代码 

 结构体的内部空间探索

题目描述

样例输入输出

代码

 字符串出现次数统计

题目描述

描述

输入描述:

输出描述:

样例输入输出

 自定义字符串输出

题目描述

样例输入输出

代码


 模版

题目描述

编写一个类模板,保存一组数据(该数据可以是int型、float型,提示:数据成员是一个一维数组,类型是虚拟类型参数),该类需要实现对输入的数据进行求和、求平均以及排序等功能。

若数据类型type为0,则表示输入数据为int型,若type为1,则表示输入数据为float型。

在主函数中测试int、float型序列数据的相关处理。

输入样式:

两行

第一行分别为数据类型type和数据个数n

第二行为n个数据,以空格分隔。

输出样式:

三行

第一行为数据之和

第二行为平均值,使用cout << setiosflags(ios::fixed)<<setprecision(2)保留两位小数,需要添加头文件iomanip。

第三行为排序后的数据,空格分隔,行尾无空格,对于浮点型数据,同样保留两位小数。

 

样例输入输出

样例1

输入:

0 10
1 2 3 4 7 8 6 5 10 9

输出:

55
5.50
1 2 3 4 5 6 7 8 9 10

样例2

输入:

1 15
1.12 2.11 3.6 9.02 7.45 8.2 9.3 20.78 77.1 8.9 12.12 44.44 32.1 29.78 10.1

输出:

276.12
18.41
1.12 2.11 3.60 7.45 8.20 8.90 9.02 9.30 10.10 12.12 20.78 29.78 32.10 44.44 77.10

代码 

#include <bits/stdc++.h>
using std::cout;
using std::cin;
using std::endl;
using std::setprecision;
using std::ios;

template <typename T>
class DataProcessor{
private:
    T* data;
    int n;
public:
    DataProcessor(int _n) : n(_n) {
        data = new T[n];
    }
    ~DataProcessor() {
        delete[] data;
    }
    void input() {
        for (int i = 0; i < n; i++) {
            cin >> data[i];
        }
    }

    void sum() {
        T sum = 0;
        for (int i = 0; i < n; i++) {
            sum += data[i];
        }
        cout << sum << endl;
    }

    void average() {
        T sum = 0;
        for (int i = 0; i < n; i++) {
            sum += data[i];
        }
        cout << setiosflags(ios::fixed) << setprecision(2) << static_cast<double>(sum)/n << endl;
    }

    void sort() {
        for(int i = 0; i < n;++i){
            for (int j = i+1; j < n; j++) {
                if (data[i] > data[j]) {
                    T temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                }
            }
        }

        for (int i = 0; i < n-1; i++) {
            cout << setiosflags(ios::fixed) << setprecision(2)  << data[i] << " ";
        }
        cout << setiosflags(ios::fixed) << setprecision(2) << data[n-1];
    }
};
int main() {
    int type, n;
    cin >> type >> n;

    if(!type) {
        DataProcessor<int> dp(n);
        dp.input();
        dp.sum();
        dp.average();
        dp.sort();
    } else if (type == 1) {
        DataProcessor<float> dp(n);
        dp.input();
        dp.sum();
        dp.average();
        dp.sort();
    } else return 1;

    return 0;
}

 模板:任意基本类型的数相加

题目描述

请用模板函数实现任意类型的数据相加。

输入:两行,每一行为一个字符s与数值n,字符s表示数据类型(b:bool, c:char, i:int, f:float, d:double),第二个数为对应的数值。注意:两个数的类型可以不一样,这时候需要按照从低往高的顺序转换,比如char和int的求和应该都使用int。

输出:两个值相加的和

请注意,对于整型类型,均按照整型加法,浮点类型均按照浮点加法。

 

样例输入输出

样例1

输入:

i 3
f 2.23

输出:

5.23

代码

#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
// 模板函数,计算两个数值的和
template <typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {
    return a + b;
}

// 将输入的字符类型和数值转换为对应的C++类型
void transformValue(char type, double& value) {
    switch (type) {
        case 'b': {
            bool temp;
            cin >> temp;
            value = static_cast<int>(temp);
            break;
        }
        case 'c': {
            char temp;
            cin >> temp;
            value = static_cast<int>(temp);
            break;
        }
        case 'i': {
            int temp;
            cin >> temp;
            value = static_cast<int>(temp);
            break;
        }
        case 'f': {
            float temp;
            cin >> temp;
            value = static_cast<double>(temp);
            break;
        }
        case 'd': {
            double temp;
            cin >> temp;
            value = temp;
            break;
        }
        default:
            break;
    }
}

int main() {
    char type1, type2;
    double value1 = 0, value2 = 0;

    cin >> type1;
    transformValue(type1, value1);

    cin >> type2;
    transformValue(type2, value2);

    auto result = add(value1, value2);

    // 输出结果,保留两位小数
    cout << result << endl;

    return 0;
}

虚函数:测试虚函数表

题目描述

请构建包含3个虚函数(用func1,func2,func3)的基类(用符号‘A’表示),以及base类的3个派生类(符号‘B’,'C','D'表示),要求均实现了基类的3个虚函数。

请打印出派生类对象的虚函数调用地址条目在虚函数表中的相对地址(相对于第一个虚函数的首地址)。

输入:一个字符(A,B,C,D)和一个整数(1,2,3)

输出:输出对应类的实例化对象对应的虚函数调用地址条目在虚函数表中的相对地址,以及该虚函数的调用结果。

 

样例输入输出

样例1

输入:

A 1

输出:

Relative address: 0
A::func1() called

样例2

输入:

C 3                 

输出:

Relative address: 16
C::func3() called

代码

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class A{
public:
    virtual void func1(){
        cout << "A::func1() called" << endl;
    }
    virtual void func2(){
        cout << "A::func2() called" << endl;
    }
    virtual void func3(){
        cout << "A::func3() called" << endl;
    }
};

class B: public A{
public:
    virtual void func1() override{
        cout << "B::func1() called" << endl;
    }
    virtual void func2() override{
        cout << "B::func2() called" << endl;
    }
    virtual void func3() override{
        cout << "B::func3() called" << endl;
    }
};

class C: public A{
public:
    virtual void func1() override{
        cout << "C::func1() called" << endl;
    }
    virtual void func2() override{
        cout << "C::func2() called" << endl;
    }
    virtual void func3() override{
        cout << "C::func3() called" << endl;
    }
};
class D: public A{
public:
    virtual void func1() override{
        cout << "D::func1() called" << endl;
    }
    virtual void func2() override{
        cout << "D::func2() called" << endl;
    }
    virtual void func3() override{
        cout << "D::func3() called" << endl;
    }
};

int main() {
    char c;
    int n;
    cin >> c >> n;
    A* newInstance = nullptr;
    if(c == 'A')
        newInstance = new A();
    else if(c == 'B')
        newInstance = new B();
    else if(c == 'C')
        newInstance = new C();
    else if(c == 'D')
        newInstance = new D();
    else 
        return 1;

    int size = sizeof(newInstance);
    cout << "Relative address: " << (n-1)*size << endl;

    switch (n)
    {
    case 1:
        newInstance->func1();
        break;
    case 2:
        newInstance->func2();
        break;
    case 3:
        newInstance->func3();
        break;
    default:
        break;
    }
    return 0;
}

虚函数:不同动物的吼声

题目描述

在一个动物园里,有许多不同种类的动物,包括狮子、老虎和熊。每种动物都有一个名字,而且每种动物都有自己的叫声。你的任务是创建一个动物类(Animal)和三个派生类(Lion,Tiger,Bear),并实现一个虚函数 makeSound(),该函数会打印出动物的叫声。

要求:

  1. Animal类应该有一个名为name的成员变量和一个名为makeSound的虚函数。
  2. Lion,Tiger,Bear类应该从Animal类派生,并且应该重写makeSound函数。
  3. Lion的makeSound函数应该打印"Roar",Tiger的makeSound函数应该打印"Growl",Bear的makeSound函数应该打印"Grr".
  4. 每个类应该有一个接受名字作为参数的构造函数,该构造函数应该设置name成员变量的值。
 

样例输入输出

样例1

输入:

Bear

输出:

Grr

代码

#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::string;

class Animal{
private:
    string name;
public:
    Animal(const string& _name):name(_name){}
    virtual void makeSound() const = 0;
    virtual ~Animal(){}

};
class Lion: public Animal{
public:
    Lion(string& _name):Animal(_name){}
    void makeSound() const override {
        cout << "Roar" << endl;
    }
};
class Tiger: public Animal{
public:
    Tiger(string& _name):Animal(_name){}
    void makeSound() const override {
        cout << "Growl" << endl;
    }
};
class Bear: public Animal{
public:
    Bear(string& _name):Animal(_name){}
    void makeSound() const override {
        cout << "Grr" << endl;
    }
};


int main() {
    string name;
    cin >> name;
    Animal* animal = nullptr; 
    if(name == "Lion")
        animal= new Lion(name);
    else if(name == "Tiger")
        animal = new Tiger(name);
    else if(name == "Bear")
        animal = new Bear(name);
    else return 1;
    
    animal->makeSound();
    delete animal;
    return 0;

}

虚函数:计算几何图形的面积和周长

题目描述

在一个二维平面上,有许多不同的几何形状,包括圆形、矩形和三角形。每种形状都有自己的面积和周长。你的任务是创建一个形状类(Shape)和三个派生类(Circle,Rectangle,Triangle),并实现两个虚函数 calculateArea() 和 calculatePerimeter(),这两个函数会返回形状的面积和周长。

要求:

  1. Shape类应该有两个虚函数calculateArea和calculatePerimeter,这两个函数应该返回double类型的值。
  2. Circle,Rectangle,Triangle类应该从Shape类派生,并且应该重写calculateArea和calculatePerimeter函数。
  3. Circle类应该有一个名为radius的成员变量,Rectangle类应该有两个名为width和height的成员变量,Triangle类应该有三个名为a,b,c的成员变量,分别代表三边的长度。
  4. 每个类应该有一个接受相应成员变量作为参数的构造函数,该构造函数应该设置相应的成员变量的值。

输入: 第一个参数为Circle,Rectangle,Triangle中的一个字符串,接下来多个浮点数,表示对应类型的参数

输出:几何图形的面积和周长

 

样例输入输出

样例1

输入:

Circle 3.14

输出:

30.9748 19.7292

样例2

输入:

Rectangle 3 4

输出:

12 14

样例3

输入:

Triangle 3.4 4.2 5.2

输出:

7.11955 12.8

 代码

#include <bits/stdc++.h>
#define PI acos(-1)
using std::cin;
using std::cout;
using std::endl;
using std::string;

class Shape {
public:
    virtual double calculateArea() = 0;
    virtual double calculatePerimeter() = 0;
    virtual ~Shape() {}
};

class Circle : public Shape {
private:
    double radius;
public:
    Circle(double _r) : radius(_r) {}
    double calculateArea() override {
        return PI * radius * radius;
    }
    double calculatePerimeter() override {
        return 2 * PI * radius;
    }
};

class Rectangle : public Shape {
private:
    double width, height;
public:
    Rectangle(double _w, double _h) : width(_w), height(_h) {}
    double calculateArea() override {
        return width * height;
    }
    double calculatePerimeter() override {
        return 2 * (width + height);
    }
};

class Triangle : public Shape {
private:
    double a, b, c;
public:
    Triangle(double _a, double _b, double _c) : a(_a), b(_b), c(_c) {}
    double calculateArea() override {
        double p = (a + b + c) / 2;
        return sqrt(p * (p - a) * (p - b) * (p - c));
    }
    double calculatePerimeter() override {
        return a + b + c;
    }
};

int main() {
    string shape;
    cin >> shape;

    if(shape == "Circle"){
        double r;
        cin >> r;
        Circle c(r);
        cout << c.calculateArea() << " " << c.calculatePerimeter() << endl;
    } else if(shape == "Rectangle"){
        double w, h;
        cin >> w >> h;
        Rectangle r(w, h);
        cout << r.calculateArea() << " " << r.calculatePerimeter() << endl;
    } else if(shape == "Triangle") {
        double a, b, c;
        cin >> a >> b >> c;
        Triangle t(a, b, c);
        cout << t.calculateArea() << " " << t.calculatePerimeter() << endl;
    } else return 1;

    return 0;

}

 学生类的定义

题目描述

要求定义一个学生类,其中数据成员:学号、姓名、数学、英语、计算机三科成绩;成员函数:求总成绩、求三科平均成绩

输入: 学号、姓名、数学、英语、计算机三科成绩
输出: 学号、姓名、数学、英语、计算机三科成绩 总成绩 三科平均成绩 

要求:学号和分数均为整数,平均成绩按四舍五入取整,输入/输出的各项之间使用空格隔开。

 

样例输入输出

样例1

输入:

1 Lucy 92 98 95

输出:

1 Lucy 92 98 95 285 95

代码 

#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::string;

class Student{
private:
    int id;
    string name;
    int math;
    int english;
    int computer;

public:
    Student(int _id, string _name, int _math, int _english, int _computer) : id(_id), name(_name), math(_math),english(_english),computer(_computer) {}
    int getSumScore(){
        return (math + english + computer);
    }
    int getAverageScore(){
        return round((math + english + computer)/3.0);
    }

};

int main(){
    int id;
    string name;
    int math, english, computer;
    cin >> id >> name >> math >> english >> computer;

    cout << id << " " << name << " " << math << " " << english << " " << computer << " ";
    Student stu(id, name, math, english, computer);
    cout << stu.getSumScore() << " " << stu.getAverageScore() << endl;
    return 0;

}

矩形重叠部分面积计算

题目描述

给你二维平面上两个由直线构成且边与坐标轴平行/垂直的矩形,请你计算并返回两个矩形重叠部分的面积。

每个矩形由其 左下 顶点和 右上 顶点坐标表示:

第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。 第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。

要求:

(1)矩形用类Rectangle表示

(2)声明友元函数friend int getArea(Rectangle m1,Rectangle m2) 来计算面积。

示例

输入格式

第 1 行:8个整数,分别是第一个矩形左下顶点 (ax1, ay1) 、右上顶点 (ax2, ay2) 、第二个矩形左下顶点 (bx1, by1) 、右上顶点 (bx2, by2)

输出格式

第 1 行:1个整数,即面积

 

样例输入输出

样例1
输入:
-3 0 3 4 0 -1 9 2
输出:
6

代码

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::max;
using std::min;

class Rectangle{
private:
    int ax1,ay1,ax2,ay2;
    int bx1,by1,bx2,by2;

public:
    Rectangle(int ax1,int ay1,int ax2,int ay2,int bx1,int by1,int bx2,int by2):ax1(ax1),ay1(ay1),ax2(ax2),ay2(ay2),bx1(bx1),by1(by1),bx2(bx2),by2(by2){}
    friend int getArea(Rectangle m1,Rectangle m2);
};

int getArea(Rectangle m1,Rectangle m2){
    int left = max(m1.ax1, m2.bx1);
    int right = min(m1.ax2, m2.bx2);
    int top = min(m1.ay2, m2.by2);
    int bottom = max(m1.ay1, m2.by1);

    if(left > right || top < bottom)
        return 0;
    return (right - left) * (top - bottom);

}

int main(){
    int ax1,ay1,ax2,ay2,bx1,by1,bx2,by2;
    cin>>ax1>>ay1>>ax2>>ay2>>bx1>>by1>>bx2>>by2;
    Rectangle m1(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2);
    cout<<getArea(m1,m1)<<endl;
    return 0;
}

点和直线的关系

题目描述

有线类(Line)和点类(Pointer),请在线类中实现一个 isPointerOfLine方法,该方法传入一个点类对象,判断点和直线的关系,并在该方法中输出。请尝试分别用友元和非友元的方式实现该功能,并体会其中的差异。

点类(Pointer):
        成员变量:x轴坐标(int x)  y轴坐标(int y)
        成员方法:成员变量的公共访问方法
线类(Line):
        成员变量:斜率(slope)  偏置/截距(bias)

        成员方法:成员变量的公共访问方法    判断点和直线关系的方法( isPointerOfLine)
点和直线的关系:
        1.点在直线的上方
        2.点恰好是直线中的一个点
        3.点在直线的下方
 

输入描述

键盘输入4个整数,分别是直线的斜率slope和截距bias,以及点的 x 坐标和 y 坐标

输出描述

直线类中实现 isPointerOfLine方法,在该方法中输出点和直线的关系,

如果点在直线的上方,则输出“upper”;

如果点是直线中的一个点,则输出“of”;

如果点在直线的下方,则输出“lower”。

 

样例输入输出

样例1

输入:

3 4 5 6

输出:

lower

样例2

输入:

3 4 5 19

输出:

of

代码

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;

class Pointer{
private:
        int x;
        int y;

public:
        Pointer(int x, int y):x(x),y(y){}
        int getX() const {return x;}
        int getY() const {return y;}
        friend class Line;
};

class Line{
private:
        int slope;
        int bias;
public:
        Line(int slope, int bias):slope(slope),bias(bias){}
        int getSlope() const {return slope;}
        int getBias() const {return bias;}

        void isPointerOfLine(const Pointer& p) const{
                int result = p.getY() - (slope * p.getX() + bias);
                if(result > 0)
                        cout << "upper" << endl;
                else if(result == 0)
                        cout << "of" << endl;
                else
                        cout << "lower" << endl;
        }

        friend void isPointerOfLineByFriend(const Line& l, const Pointer& p);

};

void isPointerOfLineByFriend(const Line& l, const Pointer& p) {
        int result = p.getY() - (l.slope * p.getX() +l. bias);
        if(result > 0)
                cout << "upper" << endl;
        else if(result == 0)
                cout << "of" << endl;
        else
                cout << "lower" << endl;        
}


int main() {
        int slope, bias;
        int x, y;
        cin >> slope >> bias >> x >> y;
        Pointer p(x, y);
        Line line(slope, bias);
        line.isPointerOfLine(p);

        return 0;

}

逃离星球计划

题目描述

在未来的一个时代,人类已经探索并殖民了多元宇宙。你是名为"Xenon"的星球的领主,这是一个人类的新殖民地,位于"U-234"宇宙。然而,你们的星球正面临一场灾难,它即将与另外一颗巨大的彗星"Folcon"相撞。你必须带领你的人民在行星撞击前逃离"Xenon"星球,以避免这场即将到来的灾难。

你的科学家们已经设计出了一种新型的宇宙飞船"Spaceship",可以用于疏散人口。你的任务需要创建和管理你的宇宙飞船,需要跟踪你创建的飞船数量,以及质量,以确保你有足够的飞船来疏散你的人民。这是一场与时间的赛跑,你必须尽快行动,否则你的人民可能会面临灾难。你准备好接受这个挑战了吗?

创建类:

1、你需要创建Universe类,用于管理多元宇宙信息,比如不同多元宇宙的万有引力常数等信息,不同宇宙的信息不同,同一宇宙的信息不可更改。

2、你需要创建Planet类,他们具有常量的质量、半径等参数,创建对象时即确定且不可更改。不同多元宇宙的Planet具有不同的Universe信息,同一宇宙的Planet必须共享同一且唯一的Universe对象。

3、你需要创建Spaceship类,用于疏散人口,该类具有加速度和最大速度等参数,每创建一艘飞船,由于质量问题,其最大速度和加速度就确定不可更改。

要求:

你需要创建"U-234"宇宙并设置该宇宙的各种常数信息;

你需要创建"Xenon"和"Folcon"星球,他们会在时间t之后相撞;

你需要创建n艘飞船,用于逃离"Xenon"星球。由于"Folcon"星球质量远远小于"Xenon"星球,假设飞船不受"Folcon"星球质量的影响,只受"Xenon"星球的万有引力,并且"Xenon"星球不相对于"Folcon"星球移动;

计算有多少艘飞船成功逃离了"Xenon"星球(在撞击时间前达到逃逸速度),并且在星球撞击时间t时各自距离"Xenon"星球的距离d。

输入:

第一行: 宇宙的万有引力常数;

第二行:两颗星球的质量、半径,以及撞击时间t;

第三行:整数n用于表示创建n艘飞船;

接下来n行:输入飞船的加速度和最大速度。

输出:

第一行:成功逃离的飞船数量m;

接下来m行:每艘飞船距离"Xenon"星球的距离(以起飞点计,达到最大速度后不再加速)。

 

样例输入输出

样例1

输入:

6e-10 
5e20 2e6 3e15 6e3 1000 
2
20 200
100 1000

输出:

1
995000

代码

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::pow;
using std::vector;

class Universe{
private:
    double gravitationConstant;//万有引力常数

public:
    Universe(double _gravitationConstant): gravitationConstant(_gravitationConstant){ }
    double getGravitationConstant() const{ return gravitationConstant; }

};

class Planet{
private:
    double mass;
    double radius;
    const Universe& universe;
public:
    Planet(double mass, double radius, const Universe& universe): mass(mass), radius(radius), universe(universe) {}

    double getMass() const{ return mass; }
    double getRadius() const{ return radius; }
    const Universe& getUniverse() const{ return universe; }
};

class Spaceship{
private:
    double acceleratedSpeed;
    double maxSpeed;
public:
    Spaceship(double acceleratedSpeed, double maxSpeed): acceleratedSpeed(acceleratedSpeed), maxSpeed(maxSpeed){}
    double getAcceleratedSpeed() const{ return acceleratedSpeed; }
    double getMaxSpeed() const{ return maxSpeed; }
};

double calculateEscapeDistance(const Planet& planet, const Spaceship& spaceship,  double impactTime) {
    double gravitationalForce = (planet.getUniverse().getGravitationConstant()*planet.getMass())/pow(planet.getRadius(), 2);//只受一个星球引力影响,F=G*m/(r^2);
    double escapeSpeed = sqrt((2*planet.getUniverse().getGravitationConstant()*planet.getMass())/planet.getRadius());//逃逸所需速度
    double escapeDistance = 0.5*spaceship.getAcceleratedSpeed()*pow(spaceship.getMaxSpeed()/spaceship.getAcceleratedSpeed(), 2)+spaceship.getMaxSpeed()*(impactTime-spaceship.getMaxSpeed()/spaceship.getAcceleratedSpeed());
    if(escapeDistance>escapeSpeed*impactTime) {
        return escapeDistance;

    } else {
        return 0;
    }
}

int main(){
    double gravitationConstant;
    cin >> gravitationConstant;

    Universe universe(gravitationConstant);
    double xeonMass, xeonRadius, folconMass, folconRadius,impactTime;
    cin >> xeonMass >> xeonRadius >> folconMass >> folconRadius >>  impactTime;
    Planet xenon(xeonMass, xeonRadius, universe);
    Planet folcon(folconMass, folconRadius, universe);
    int numberOfSpaceships;
    cin >> numberOfSpaceships;

    vector<double> escapeDistances;

    for(int i = 0; i < numberOfSpaceships;++i) {
        double acceleratedSpeed, maxSpeed;
        cin >> acceleratedSpeed >> maxSpeed;
        Spaceship spaceship(acceleratedSpeed, maxSpeed);
        // calculateEscapeDistance(xenon, spaceship, impactTime);
        int distance = calculateEscapeDistance(xenon, spaceship, impactTime);
        if(distance)
            escapeDistances.push_back(distance);

    }

    cout << escapeDistances.size() << endl;
    for(double distance : escapeDistances)  cout << distance << endl;

    return 0;
}

面向对象的Tensor

题目描述

使用类和对象等面向对象特性,设计一个高维数据结构Tensor类,并设计成员函数输出Tensor的维度和打印Tensor元素等信息。要求:

(1)包含一个int类型动态数组data成员变量。
(2)包含成员函数createTensor(int dim_num, int* dim_value):设置Tensor的维度和大小,按行优先,从1开始,按序生成Tensor数据

          GetSize():计算Tensor的尺寸并返回

          GetElement(int* dim_index):获取Tensor中对应坐标的元素。

(3)包含成员函数Display():逐行打印Tensor的所有元素。

input
输入Tensor的维度dim_num

输入dim_num个正整数(需要判断是否为正),表示Tensor每一个维度的大小

输入dim_num个整数(需要判断是否非负),表示获取Tensor中指定索引处的元素值

output

输出Tensor的尺寸

输出Tensor中指定位置元素

打印ensor的所有元素

 

样例输入输出

样例2

输入:

3
3 2 3
2 1 1

输出:

18
17
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18

样例2

输入:

2
3 3
2 2

输出:

9
9
1 2 3
4 5 6
7 8 9

代码

#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::vector;

class Tensor {
private:
    vector<int> data;
    vector<int> dimensions;
    int size;

public:
    void createTensor(int dim_num, int* dim_value) {
        dimensions.clear();
        dimensions.reserve(dim_num);
        
        // 计算size
        size = 1;
        for (int i = 0; i < dim_num; ++i) {
            dimensions.push_back(dim_value[i]);
            size *= dim_value[i];
        }

        // 生成Tensor数据
        data.clear();
        data.resize(size);
        int element = 1;
        for (int i = 0; i < size; ++i) {
            data[i] = element++;
        }
    }

    int GetSize() const {
        return size;
    }

    int GetElement(int* dim_index) const {
        int index = 0;
        int multiplier = 1;
        for (int i = dimensions.size() - 1; i >= 0; --i) {
            if (dim_index[i] < 0 || dim_index[i] >= dimensions[i])  return 1;
            index += dim_index[i] * multiplier;
            multiplier *= dimensions[i];
        }
        return data[index];
    }

    void Display() const {
        int lineEndPos =  dimensions[dimensions.size()-1];
        for (int i = 0; i < size; ++i) {
            if((i+1) % lineEndPos == 0) {cout << data[i] << endl;}
            else {cout << data[i] << " ";}
        }
    }
};

int main() {
    int dim_num;
    cin >> dim_num;

    if (dim_num <= 0) return 1;

    int* dim_value = new int[dim_num];
    for (int i = 0; i < dim_num; ++i) {
        cin >> dim_value[i];
        if (dim_value[i] <= 0) {
            delete[] dim_value;
            return 1;
        }
    }

    Tensor tensor;
    tensor.createTensor(dim_num, dim_value);

    int* dim_index = new int[dim_num];
    for (int i = 0; i < dim_num; ++i) {
        cin >> dim_index[i];
        if (dim_index[i] < 0 || dim_index[i] >= dim_value[i]) {
            delete[] dim_value;
            delete[] dim_index;
            return 1;
        }
    }

    cout << tensor.GetSize() << endl;
    cout << tensor.GetElement(dim_index) << endl;
    tensor.Display();

    delete[] dim_value;
    delete[] dim_index;

    return 0;
}

实现Tensor的简单计算

题目描述

构建Tensor类型,并使用0作为随机种子,根据输入的shape,生成随机的Tensor对象。

实现简单的两个Tensor的加,并输出Tensor相加的结果。

输入:连续n那个整型数按空格隔开,表示Tensor的形状

输出:生成的两个Tensor求和的结果,按照最后两维的形状隔行打印到屏幕

 

样例输入输出

样例1

输入:

2 3

输出:

Tensor 1:
0.548814 0.592845 0.715189
0.844266 0.602763 0.857946

Tensor 2:
0.544883 0.847252 0.423655
0.623564 0.645894 0.384382

Tensor 1 + Tensor 2:
1.0937 1.4401 1.13884
1.46783 1.24866 1.24233

样例2

输入:

2 3 4

输出:

Tensor 1:
0.548814 0.592845 0.715189 0.844266
0.602763 0.857946 0.544883 0.847252
0.423655 0.623564 0.645894 0.384382

0.437587 0.297535 0.891773 0.056713
0.963663 0.272656 0.383442 0.477665
0.791725 0.812169 0.528895 0.479977

Tensor 2:
0.568045 0.392785 0.925597 0.836079
0.0710361 0.337396 0.0871293 0.648172
0.0202184 0.368242 0.83262 0.957155

0.778157 0.140351 0.870012 0.870087
0.978618 0.473608 0.799159 0.800911
0.461479 0.520477 0.780529 0.67888

Tensor 1 + Tensor 2:
1.11686 0.985629 1.64079 1.68034
0.673799 1.19534 0.632012 1.49542
0.443873 0.991805 1.47851 1.34154

1.21574 0.437885 1.76179 0.9268
1.94228 0.746264 1.1826 1.27858
1.2532 1.33265 1.30942 1.15886

代码

#include <bits/stdc++.h>
using namespace std;

class Tensor{
private:
    vector<int> shape;
    vector<float> data;
public:
    Tensor(vector<int>& shape) :shape(shape) {
        int totalSize = 1;
        for(int dim:shape) totalSize *= dim;
        totalSize *=2;//直接存储两个tensor,方便运算
        data.resize(totalSize);
    }

    void Generate(){
		mt19937 generator(0);
		uniform_real_distribution<float> dis(0.0, 1.0);
		
		for(float& value: data) value = dis(generator);
    }

    vector<int> getShape() const {return shape;}

    vector<float> getValue() const {return data;}

    void printTensor(const Tensor& tensor){
        int num_dim;
        vector<int> shape = tensor.getShape();
        vector<float> data = tensor.getValue();

        int numCols = shape[shape.size()-1];
        int numRows = shape[shape.size()-2];
        int totalSize = data.size();
        int singleSize = totalSize/2;

        cout << "Tensor 1:" << endl;

        for(int i = 0; i < singleSize;++i){
            if(!((i+1)%(numCols*numRows)))
                cout << data[i] << "\n\n";
            else if(!((i+1)%numCols))//行末且非每个矩阵最末元素
               cout << data[i] << endl;
            else 
                cout << data[i] << " " ;

        }

        cout << "Tensor 2:" << endl;

        for(int i = singleSize; i < totalSize;++i){
            if(!((i+1)%(numCols*numRows)))
                cout << data[i] << "\n\n";
            else if(!((i+1)%numCols))//行末且非每个矩阵最末元素
               cout << data[i] << endl;
            else 
                cout << data[i] << " " ;

        }

        cout << "Tensor 1 + Tensor 2:" << endl;
        for(int i = 0; i< singleSize; ++i){
            if(i==singleSize-1){
                cout << data[i]+data[singleSize+i];
            }
            else if(!((i+1)%(numCols*numRows)))
                cout << data[i]+data[singleSize+i] << "\n\n";
            else if(!((i+1)%numCols))
                cout << data[i]+data[singleSize+i] << endl;            
            else 
                cout << data[i]+data[singleSize+i] << " ";            

        }
    }

};

int main() {
    //输入数据处理
    vector<int> shape;
    string line;
    getline(cin, line);
    int n;
    istringstream iss(line);
    while(iss >> n) shape.push_back(n);

    Tensor tensor(shape);
    tensor.Generate();
    tensor.printTensor(tensor);
    return 0;
}

友元-输出两坐标点之间的距离

题目描述

定义一个Point类,包含私有数据成员为浮点数类型x和y,以及成员函数display()输出点的坐标,

在类外定义一个普通函数distance(),在Point类中将其声明为友元函数,在主函数中调用distance函数,输出两个坐标点之间的距离。

输入:

4个数,分别是A、B坐标点x和y的值,用空格分隔;

输出:

(A.x, A.y)

(B.x, B.y)

A、B坐标间的距离,保留两位小数。 

 

样例输入输出

样例1

输入:

1.2 2 3 4.2

输出:

(1.2, 2)
(3, 4.2)
2.84

 代码

#include<bits/stdc++.h>
using std:: cin;
using std:: cout;
using std:: endl;

class Point{
private:
    double x;
    double y;


public:
    Point(double _x, double _y):x(_x), y(_y) {}

    void display(){
        cout << "(" << x << ", " << y << ")" << endl;
    }

    friend double Distance(const Point& A, const Point& B);

};

double Distance(const Point& A,const Point& B){
    double dx = A.x - B.x;
    double dy  = A.y - B.y;
    return sqrt(dx*dx + dy*dy);
}

int main(){
    double x1,y1,x2,y2;
    cin >> x1 >> y1 >> x2 >>y2;

    Point A(x1,y1),B(x2,y2);
    A.display();
    B.display();
    printf("%.2f",Distance(A,B));

    return 0;
}

类的定义

题目描述

设计一个立方体类Box,它能计算并输出立方体的体积和表面积。要求:

(1)包含成员变量m_a(立方体边长)。
(2)包含函数SetA(double a)(设置立方体边长)、GetVolume()(计算体积)、GetArea()(计算表面积)。
(3)包含函数Display(),用来输出计算的结果。

input

立方体边长,浮点类型。

output

输出为两行,第一行是体积,第二行是面积

 

样例输入输出

样例1

输入:

5

输出:

125
150

代码

#include <iostream>
using namespace std;

class Box{
private:
    double m_a;

public:
    void SetA(double a){
        m_a = a;
    }

    double GetVolume(){
        return m_a*m_a*m_a;
    }

    double GetArea(){
        return m_a*m_a*6;
    }

    void Display(){
        double area = GetArea();
        double volume = GetVolume();
        cout << volume << endl;
        cout << area << endl;
    }


};
int main(){
    double n;
    cin >> n;

    Box box;
    box.SetA(n);
    box.Display();
    return 0;
}

计算矩阵的行列式

题目描述

矩阵的行列式是一个可以从方阵中计算得出的特殊数值,其在数学和科学中有许多重要的应用,比如,如果一个矩阵的行列式不为零,那么这个矩阵是可逆的,可以用来解线性方程组。

计算矩阵行列式的递归算法通常遵循以下步骤:

  1. 基本情况:如果矩阵是1x1的,那么行列式就是矩阵中的那个元素。如果矩阵是2x2的,那么行列式就是对角线元素的乘积减去另外两个元素的乘积。

  2. 递归步骤:如果矩阵的大小大于2,那么行列式可以通过以下方式计算:

    • 对于矩阵的每一列(或每一行),计算该元素的余子式(cofactor)。余子式是通过删除当前元素所在的行和列后得到的矩阵的行列式。
    • 将每个元素与其余子式的乘积加起来,得到的和就是原矩阵的行列式。注意,根据元素的位置,可能需要给余子式加上负号。

算法的伪代码如下:

function calculateDeterminant(matrix):
    if matrix is 1x1:
        return the single element in matrix
    if matrix is 2x2:
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
    else:
        determinant = 0
        for each element in the first row of matrix:
            cofactor = calculateDeterminant(submatrix obtained by removing the row and column of the element)
            if the column of the element is odd:
                cofactor = -cofactor
            determinant += element * cofactor
        return determinant

其中的余子式(Cofactor)是在矩阵中删除特定行和列后得到的子矩阵的行列式。

比如,对于一个7x7的矩阵,如果我们在(5,5)处计算余子式,我们会删除第5行和第5列,这将会得到一个6x6的子矩阵。所以,(5,5)处的余子式是一个6x6矩阵的行列式。

该算法的时间复杂度是O(n!),其中n是矩阵的大小,因为对于每个元素,我们都需要计算一个较小的矩阵的行列式。

请构建Matrix类型,并实现其构造函数、余子式获取函数、行列式计算函数。输入为Matrix的行和列,设随机种子为0,生成随机矩阵。输出矩阵,然后输出矩阵的行列式。

如果输入矩阵不是方阵,

首先输出生成的随机矩阵,然后输出error.

输入:矩阵的行和列

输出:矩阵元素以及矩阵行列式

 

样例输入输出

样例1

输入:

3 3

输出:

0.548814 0.592845 0.715189
0.844266 0.602763 0.857946
0.544883 0.847252 0.423655
0.0829981

代码

#include<bits/stdc++.h>
using namespace std;

class Matrix {
private:
    vector<vector<float>> matrix;
    int rows, cols;
public:
    Matrix(int rows, int cols) : rows(rows), cols(cols) {
        matrix.resize(rows, vector<float>(cols, 0.0));
        mt19937 generator(0);
        uniform_real_distribution<float> dis(0.0,1.0);
        for(int i=0; i<rows; ++i){
            for(int j=0; j<cols; ++j){
                matrix[i][j] = dis(generator);
            }
        }
    
    }
    Matrix getSubMatrix(int row, int col) const{
        Matrix res(rows-1, cols-1);//余子式
        int r_i = 0;
        for(int i=0; i<rows; ++i){
            if(i == row) continue;
            int r_j = 0;
            for(int j=0; j<cols; ++j){
                if(j==col) continue;
                res.matrix[r_i][r_j] = matrix[i][j];
                ++r_j;
            }
            ++r_i;
        }
        return res;
    }

    float calculateDeterminant() const{
        float res = 0;
        if(rows!=cols) {
            return 0.0;
        }
        else if(rows==1) return matrix[0][0];
        else if(rows==2) return matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1];
        else {
            for(int j=0; j<cols; ++j){
                Matrix sub = getSubMatrix(0,j);
                float cofactor = sub.calculateDeterminant(); 
                if(j%2) cofactor *=-1;
                res += cofactor*matrix[0][j];
            }

            return res;
        }
    }
    void print(){
        for(int i=0; i<rows;++i){
            for(int j=0; j<cols;++j){
                if(j == cols-1)
                    cout << matrix[i][j] << endl;
                else
                    cout << matrix[i][j] << " ";
            }
        }
    }


};

int main(){
    int rows, cols;
    cin >> rows >> cols;

    if(rows <=0 || cols <=0) return 1;
    Matrix m(rows, cols);
    m.print();
    if(rows==cols)
        cout << m.calculateDeterminant();
    else cout << "error";

    return 0;
}

生成随机的Tensor张量

题目描述

使用随机数生成一个Tensor并打印到屏幕。

输入为连续的多个整数,分别为Tensor的维度,以及每个维度的尺寸。

程序需要根据给出的维度和各维度的值创建Tensor对象,并使用随机数生成器为Tensor赋初始值,然后将Tensor打印到屏幕,打印规则为将高维Tensor展开为多个大小为Tensor最后两个维度的多个矩阵,向屏幕打印每个矩阵,相邻的两个矩阵间多一空行隔开。

要求:

1、generate函数:设置随机种子为0,参照随机数生成器的代码生成0.0-1.0之间的随机浮点

2、create函数:创建Tensor对象

3、display函数:打印Tensor数据

示例:

输入:

2
2 2

输出:

0.548814 0.592845
0.715189 0.844266

样例输入输出

样例2

输入:

3
3 2 4

输出:

0.548814 0.592845 0.715189 0.844266
0.602763 0.857946 0.544883 0.847252

0.423655 0.623564 0.645894 0.384382
0.437587 0.297535 0.891773 0.056713

0.963663 0.272656 0.383442 0.477665
0.791725 0.812169 0.528895 0.479977

样例1

输入:

2
3 4

输出:

0.548814 0.592845 0.715189 0.844266
0.602763 0.857946 0.544883 0.847252
0.423655 0.623564 0.645894 0.384382

代码

#include<bits/stdc++.h>
using namespace std;

class Tensor{
private:
	vector<int> shape;//各个维度大小
	vector<float> data;//总数据量
	
public:
	Tensor(const vector<int>& dims) : shape(dims){
		int totalSize = 1;
		for(int dim: dims) totalSize*= dim;
		
		data.resize(totalSize);//扩容
		Generate();
	}
	
	void Generate(){
		mt19937 generator(0);//0作为种子
		uniform_real_distribution<float> dis(0.0, 1.0);
		
		for(float& value: data){
			value = dis(generator);
		}
		
	}
	
	void Display() const {
		int totalSize = data.size();
		int numRows = shape[shape.size() - 2];
		int numCols = shape[shape.size()- 1];

        for(int i = 0; i < totalSize;++i){
			if(i == totalSize-1) 
			    cout << data[i];
            else if(!((i+1)%(numCols*numRows)))
                cout << data[i] << "\n\n";
            else if(!((i+1)%numCols))//行末且非每个矩阵最末元素
               cout << data[i] << endl;
            else 
                cout << data[i] << " " ;

        }
	}
};

int main(){
	int numDims;
	cin >> numDims; // 读取Tensor的维度
	
	// 读取Tensor的形状
	vector<int> shape(numDims);
	// shape.push_back(numDims);
	for (int i = 0; i < numDims; ++i) {
		cin >> shape[i];
	}
	
	Tensor tensor(shape);	
	tensor.Display();
	
	return 0;
}

链表:删除链表的倒数第 n 个结点

题目描述

设计一个链表,随机插入和删除链表的多个结点,最后倒序输出链表的所有内容。

输入:输入一个整数n

            接下来n行分别输入两个整数value, position以及一个字符(值可能为 i/d),用于表示在对应位置插入/删除链表节点

输出:倒序输出链表的所有内容

 

样例输入输出

样例1

输入:

3
1 0 i
2 0 i
3 1 i

输出:

1 3 2

样例2

输入:

6
10 0 i
20 1 i
30 2 i
40 3 i
0 2 d
0 3 d

输出:

40 20 10

代码

#include <bits/stdc++.h>
using namespace std;

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int val): val(val), next(NULL) {}
};

class LinkedList {
private:
    ListNode *head;

public:
    LinkedList() {
        head = NULL;
    }
    void insertNode(int val, int position) {
        ListNode *newNode = new ListNode(val);
        if (position == 0 || head == NULL) {
            newNode->next = head;
            head = newNode;
            return;
        }
        ListNode *prev = head;
        for (int i = 0; i < position - 1 && prev->next != NULL; i++) {
            prev = prev->next;
        }
        newNode->next = prev->next;
        prev->next = newNode;
    }

    void deleteNode(int position) {
        if (head == NULL)
            return;
        ListNode *temp = head;
        if (position == 0) {
            head = head->next;
            delete temp;
            return;
        }
        for (int i = 0; temp != NULL && i < position - 1; i++)
            temp = temp->next;
        if (temp == NULL || temp->next == NULL)
            return;
        ListNode *next = temp->next->next;
        delete temp->next;
        temp->next = next;
    }

    void reverseList() {
        ListNode *prev = NULL;
        ListNode *current = head;
        ListNode *next;
        while (current != NULL) {
            next = current->next;
            current->next = prev;
            prev = current;
            current = next;
        }
        head = prev;
    }

    void printList() {
        ListNode *temp = head;
        while (temp != NULL) {
            if(temp->next == NULL) 
                cout << temp->val;
            else cout << temp->val << " ";
            temp = temp->next;
        }
        cout << endl;
    }
};

int main() {
    int n;
    cin >> n;
    LinkedList ll;
    
    for (int i = 0; i < n; i++) {
        int value, position;
        char op;
        cin >> value >> position >> op;
        if (op == 'i') {
            ll.insertNode(value, position);
        } else if (op == 'd') {
            ll.deleteNode(position);
        }
    }
    
    ll.reverseList();
    ll.printList();
    return 0;
}

重载运算符练习

题目描述

定义一个RMB类Money,包括元角分三个数据成员,重载运算符'+'和'-',实现货币的加减运算。

例如:

输入一组元角分:

2 3 4

3 7 3

输出:

和:6元0角7分

差:-1元3角9分

 

样例输入输出

样例1

输入:

2 3 4
3 7 3

输出:

和:6元0角7分
差:-1元3角9分

样例2

输入:

2 3 0
1 6 0

输出:

和:3元9角0分
差:0元7角0分

代码

#include<bits/stdc++.h>
using namespace std;

class Money {
private:
	int yuan;  // 元
	int jiao;  // 角
	int cent;   // 分
	
public:
	Money(int yuan_, int jiao_, int cent_) : yuan(yuan_), jiao(jiao_), cent(cent_) {}
	
	Money operator+(const Money& other) const {
		int total_cent = yuan * 100 + jiao * 10 + cent + other.yuan * 100 + other.jiao * 10 + other.cent;
		int new_yuan = total_cent / 100;
		int new_jiao = (total_cent % 100) / 10;
		int new_cent = total_cent % 10;
		return Money(new_yuan, new_jiao, new_cent);
	}
	
	Money operator-(const Money& other) const {
		int total_cent = yuan * 100 + jiao * 10 + cent - (other.yuan * 100 + other.jiao * 10 + other.cent);
		int new_yuan = total_cent / 100;
		int new_jiao = (total_cent % 100) / 10;
		int new_cent = total_cent % 10;
		return Money(new_yuan, new_jiao, new_cent);
	}
	
	friend ostream& operator<<(ostream& os, const Money& money) {
		if(money.yuan < 0 || money.jiao < 0 || money.cent <0)
			os << "-" << abs(money.yuan) << "元" << abs(money.jiao) << "角" << abs(money.cent) << "分" << endl;
		else	
		os << money.yuan << "元" << money.jiao << "角" << money.cent << "分" << endl;

		return os;
	}
};

int main() {
	int yuan1, jiao1, cent1, yuan2, jiao2, cent2;
	cin >> yuan1 >> jiao1 >> cent1 >> yuan2 >> jiao2 >> cent2;
	
	Money money1(yuan1, jiao1, cent1);
	Money money2(yuan2, jiao2, cent2);
	
	Money sum = money1 + money2;
	Money diff = money1 - money2;
	
	cout << "和:" << sum;
	cout << "差:" << diff;
	
	return 0;
}

运算符重载:复数类的运算

题目描述

描述: 请创建一个名为Complex的类,用于表示复数。这个类需要重载加法运算符+和减法运算符-,以便能够进行复数的加减运算。

输入: 输入包含两行,每行包含两个整数,分别表示复数的实部和虚部。

输出: 输出包含两行,第一行表示两个复数的和,第二行表示两个复数的差。每行输出的格式为"a + bi",其中a和b分别表示复数的实部和虚部。

示例:

输入:

1 1

2 2

输出:

3 + 3i

-1 - 1i

注意:请确保你的类能够处理负数的情况。

 

样例输入输出

样例1

输入:

1 1
2 2

输出:

3 + 3i
-1 - 1i

代码

#include <bits/stdc++.h>
using namespace std;

class Complex {
private:
	int real;
	int imaginary;
	
public:
	Complex(int r, int i){
		real = r;
		imaginary = i;
	}
	
	//重载加法运算符
	Complex operator+(const Complex& other){
		return Complex(real + other.real, imaginary + other.imaginary);
	}
	//重载减法运算符
	Complex operator-(const Complex& other){
		return Complex(real-other.real, imaginary-other.imaginary);
	}
	
	void Print(){
		if(imaginary >= 0)
			cout << real << " + " << imaginary << "i" << endl;
		else {
			cout << real << " - " << abs(imaginary) << "i" << endl;
		}
	}
};

int main(){
	int r1,i1,r2,i2;
	cin >> r1 >> i1;
	cin >> r2 >> i2;

	Complex result1(r1,i1);
	Complex result2(r2,i2);
	Complex sum = result1+result2;
	sum.Print();
	Complex diff = result1-result2;
	diff.Print();
	return 0;
}

 运算符重载:坐标运算

题目描述

请创建一个名为Point和一个名为Polar的类,分别用于表示笛卡尔坐标和极坐标下的点。

实现这两个类的加和减法,需要重载加法运算符+和减法运算符-,以便能够进行笛卡尔坐标和极坐标的加减运算。

输入: 输入包含三行,前两行每行包含两个浮点数, 一个字符p/q分别表示Point和Polar的坐标, 最后一行输入一个字符+/-表示运算符。输入错误的符号则输出error。

输出: 输出运算结果,运算结果应该为两行,第一行为笛卡尔坐标下的结果的两个坐标,第二行为极坐标下的运算结果的两个坐标。

注意:  对于极坐标,你总是需要将其坐标转换到笛卡尔坐标下进行计算,然后再转换回极坐标,来“加”这两个极坐标。极坐标的角度为弧度,范围为[-pai,pai]。 使用float数据类型来存储和计算坐标.,使用atan2计算弧度。

 

样例输入输出

样例1

输入:

2 3 p
4 5 p
+

输出:

(6, 8)
(10, 0.927295)

样例2

输入:

2 3 p 
5 3.1415926 q
+

输出:

(-3, 3)
(4.24264, 2.35619)

样例3

输入:

2.14 3.14 q
4.5 6.8 p
-

输出:

(-6.64, -6.79659)
(9.50175, -2.34454)

代码

#include <bits/stdc++.h>
using namespace std;


class Polar;

class Point {
private:
	float x, y;
	
public:
	Point(float x_, float y_) : x(x_), y(y_) {}
	
	Point operator+(const Point& other) const {
		return Point(x + other.x, y + other.y);
	}
	
	Point operator-(const Point& other) const {
		return Point(x - other.x, y - other.y);
	}
	
	friend ostream& operator<<(ostream& os, const Point& p) {
		os << "(" << p.x << ", " << p.y << ")";
		return os;
	}
	
	// 转换为极坐标
	Polar toPolar() const;
};

class Polar {
private:
	float radius, angle; 
	
public:
	Polar(float radius_, float angle_) : radius(radius_), angle(angle_) {}
	
	Polar operator+(const Polar& other) const {
		float x1 = radius * cos(angle);
		float y1 = radius * sin(angle);
		float x2 = other.radius * cos(other.angle);
		float y2 = other.radius * sin(other.angle);
		return Point(x1 + x2, y1 + y2).toPolar();
	}
	
	Polar operator-(const Polar& other) const {
		float x1 = radius * cos(angle);
		float y1 = radius * sin(angle);
		float x2 = other.radius * cos(other.angle);
		float y2 = other.radius * sin(other.angle);
		return Point(x1 - x2, y1 - y2).toPolar();
	}
	
	friend ostream& operator<<(ostream& os, const Polar& p) {
		os << "(" << p.radius << ", " << p.angle << ")";
		return os;
	}
	// 转换为笛卡尔坐标
	Point toCartesian() const {
		float x_ = radius * cos(angle);
		float y_ = radius * sin(angle);
		return Point(x_, y_);
	}
};

// 转换为极坐标
Polar Point::toPolar() const {
	float radius = sqrt(x * x + y * y);
	float angle = atan2(y, x); 
	return Polar(radius, angle);
}

int main() {
	float x1, y1, x2, y2;
	char type1,type2, op;
	bool op_input;
	cin >> x1 >> y1 >> type1;
	cin >> x2 >> y2 >> type2;
	cin >> op;
	if (op != '+' && op != '-') {
		cout << "error" << endl;
		return 0;
	}
	if(op == '+') op_input = true;
	else op_input = false;
	
	if (type1 == 'p' && type2 == 'p') {
		Point p1(x1, y1), p2(x2, y2);
		if (op_input) {
			cout << p1 + p2 << endl;
			cout << p1.toPolar() + p2.toPolar() << endl;
		} else {
			cout << p1 - p2 << endl;
			cout << p1.toPolar() - p2.toPolar() << endl;
		}
	} else if (type1 == 'q' && type2 == 'q') {
		Polar p1(x1, y1), p2(x2, y2);
		if (op_input) {
			cout << p1.toCartesian() + p2.toCartesian() << endl;			
			cout << p1 + p2 << endl;
		} else {
			cout << p1.toCartesian() - p2.toCartesian() << endl;			
			cout << p1 - p2 << endl;
		}
	} else if(type1 == 'p' && type2 == 'q'){
		Point p1(x1, y1);
		Polar p2(x2,y2);
		if(op_input){
			cout << p1 + p2.toCartesian() << endl;			
			cout << p1.toPolar() + p2 << endl;
		} else {
			cout << p1 - p2.toCartesian() << endl;			
			cout << p1.toPolar() - p2 << endl;			
		}		
	} else if(type1 == 'q' && type2 == 'p'){
		Polar p1(x1, y1);
		Point p2(x2, y2);
		if(op_input){
			cout << p1.toCartesian() + p2 << endl;			
			cout << p1 + p2.toPolar() << endl;			
		} else {
			cout << p1.toCartesian() - p2 << endl;			
			cout << p1 - p2.toPolar() << endl;			
		}	
	}
	else {
		cout << "error" << endl;
	}
	
	return 0;
}

 函数:时间制度转换

题目描述

编写函数将24小时制度转换为12小时制度,例如将14:25转换为2:25PM,8:01即为8:01AM

输入描述:输入为字符串表示的时间,例如14:25

输出描述:12小时制,2:25PM

 

样例输入输出

样例1

输入:

14:25

输出:

2:25PM

样例2

输入:

8:01

输出:

8:01AM

代码

#include <bits/stdc++.h>
using namespace std;


bool isValidTime(string time24) {
	if (time24.length() == 4) {
		time24 = "0" + time24;//对齐
	}
	string hourStr = time24.substr(0, 2);
	string minuteStr = time24.substr(3, 2);
	
	int hour = stoi(hourStr);
	int minute = stoi(minuteStr);
	
	return (hour >= 0 && hour < 24 && minute >= 0 && minute < 60);
}

string convertHour(string time24) {
	if (!isValidTime(time24)) {
		return "error";
	}
	if (time24.length() == 4) {
		time24 = "0" + time24;
	}	
	string hourStr = time24.substr(0, 2);
	string minuteStr = time24.substr(3, 2);
	

	int hour = stoi(hourStr);
	
	string period = "AM";
	if (hour >= 12) {
		period = "PM";
		if (hour > 12) {
			hour -= 12;
		}
	}
	if (hour == 0) {
		hour = 12;
	}
	
	return to_string(hour) + ":" + minuteStr + period;
}

int main() {
	string time24;
	cin >> time24;
	
	string time12 = convertHour(time24);
	cout << time12 << endl;
	
	return 0;
}

函数:计算x的y次幂

题目描述

编写函数计算x的y次幂

输入描述:x和y的值 如:2 3

输出描述:x的y次幂 如:8

 

样例输入输出

样例1

输入:

2 3

输出:

8

 代码

#include <bits/stdc++.h>
using namespace std;


int power(int x, int y) {
	if (y == 0) {
		return 1;
	}
	int result = 1;
	for (int i = 0; i < abs(y); i++) {
		result *= x;
	}
	return (y > 0) ? result : 1 / result;
}

int main() {
	int x;
	int y;
	cin >> x >> y;
	
	int result = power(x, y);
	cout << result << endl;
	
	return 0;
}

角谷猜想

题目描述

(满分100分,本题20分)


一位中学生发现一个奇妙的“定理”,请角谷教授证明,而教授无能为力,于是产生角谷猜想。

猜想的内容是:任给一个自然数,若为偶数除以2,若为奇数则乘3加1,得到一个新的自然数后按照上面的法则继续演算,若干次后得到的结果必然为1。请编程验证该猜想。

输入描述:

任一正整数 n(1<= n <=1000)

输出描述:

演算的过程,直到结果为1。

 

样例输入输出

样例1

输入:

10

输出:

10/2=5
5*3+1=16
16/2=8
8/2=4
4/2=2
2/2=1

代码

#include <bits/stdc++.h>
using namespace std;

bool CollatzConjecture(int n) {
	while (n != 1) {
		if (n % 2 == 0) {
			cout << n << "/2=" << n/2 << endl;
			n /= 2;
		} else {
			cout << n << "*3+1=" << n*3+1 << endl;
			n = n * 3 + 1;
		}
	}
	return true;
}

int main() {
	int n;
	cin >> n;
	if (n>=1 && n <=1000)
		CollatzConjecture(n);
		
	return 0;
}

函数:计算兔子数量

题目描述

有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第 n 个月的兔子对数为多少?

输入描述:键盘输入任意一个正整数 n,n 的范围为 [1, 20]

输出描述:输出第 n 个月兔子的对数 

 

样例输入输出

样例1

输入:

1

输出:

1

样例2

输入:

2

输出:

1

样例3

输入:

3

输出:

2

样例4

输入:

4

输出:

3

代码

#include <bits/stdc++.h>
using namespace std;

int fibonacci(int n) {
	if (n <= 2) {
		return 1;
	}
	return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
	int n;
	cin >> n;
	if(n>=1 && n <=20)
		cout << fibonacci(n) << endl;
	else 
		return 1;
	
	return 0;
}

计算h指数

题目描述

输入连续多个整数,并存储为一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数

h指数的计算方式:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。

输入:连续的n个整数,用空格隔开

输出:h指数值

 

样例输入输出

样例1

输入:

3 4 0 12 5 7

输出:

4

样例2

输入:

3 0 6 1 5

输出:

3

代码

#include <bits/stdc++.h>
using namespace std;


int hIndex(vector<int>& citations) {
	// 按引用次数降序排序
	sort(citations.begin(), citations.end(), greater<int>());
	
	int h = 0; 
	for (int i = 0; i < int(citations.size()); ++i) {
		// 若引用次数大于等于当前索引加1,更新h指数
		if (citations[i] >= i + 1) {
			h = i + 1;
		} else break;
	}
	return h;
}

int main() {
	vector<int> citations;
	int num;
	
	while (cin >> num) {
		if(num<0) return 1;
		if(cin.peek() == '\n') break;
		citations.push_back(num);
	}
	
	int hIndexValue = hIndex(citations);
	cout << hIndexValue << endl;
	
	return 0;
}

按频率排序字符串

题目描述

输入一个字符串,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。如果两个字符的频率相同,则按照其字母表顺序排序。

输入:一个字符串。

输出:排序后的字符串。

 

样例输入输出

样例1

输入:

gggffffssssseeeekkkkaaa

输出:

ssssseeeeffffkkkkaaaggg

样例2

输入:

hello world

输出:

llloo dehrw

 代码

#include <bits/stdc++.h>
using namespace std;

string frequencySort(string str) {
	unordered_map<char, int> mp;
	//记录出现频率
	for (auto& c : str)
		mp[c]++;
	
	sort(str.begin(), str.end(), [&](char& a, char& b) {
		if (mp[a] == mp[b])
			return a < b;  
		return mp[a] >= mp[b];  
	});
	
	return str;
}
int main() {
	string input;
	getline(cin, input);
	string result = frequencySort(input);
	cout << result << endl;
	
	return 0;
}

相邻元素最大距离

题目描述

连续输入多个无序整数以空格隔开,并存储为一个数组 nums,返回数组在排序之后,相邻元素之间最大的差值 。

输入:连续多个整数并以空格隔开。

输出:排序后数组相邻元素的最大差值。

 

样例输入输出

样例1

输入:

1 4 3 7 2 9 12 15 6

输出:

3

代码

#include <bits/stdc++.h>
using namespace std;

int maxNumGap(vector<int>& nums) {
	int n = nums.size();
	if (n < 2) return 0;
	
	sort(nums.begin(), nums.end()); 
	
	int maxgap = 0;
	for (int i = 1; i < n; ++i) {
		int gap = nums[i] - nums[i - 1];
		maxgap = max(maxgap, gap);
	}
	
	return maxgap;
}
int main() {
	vector<int> nums;
	int num;
	
	while (cin >> num) {
		nums.push_back(num);
		if (cin.get() == '\n') break; 
	}
	int maxgap = maxNumGap(nums);
	cout << maxgap << endl;
	
	return 0;
}

 数组合并

题目描述

输入两个按 非递减顺序 排列的长度分别为m和n的整数数组 nums1 和 nums2

请 合并 nums1 和  nums 两个数组为一个新的数组,并且使合并后的数组同样按 非递减顺序 排列。

输入:第一行分别输入m和n,

第二行输入m个整数

第三行输入n个整数

输出:输出合并后的数组

 

样例输入输出

样例1

输入:

3 4
1 4 5 
6 8 10 13

输出:

1 4 5 6 8 10 13

样例2

输入:

3 4
5 7 9
1 4 6 8 

输出:

1 4 5 6 7 8 9

代码

#include <bits/stdc++.h>
using namespace std;

bool mergeNums(vector<int>& nums1, vector<int>& nums2, vector<int>::size_type m, vector<int>::size_type n) {
	if (m == 0 || n == 0) return false;
	if (m != nums1.size() || n != nums2.size()) return false;
	vector<int> mergednums;
	vector<int>::size_type i = 0, j = 0;
	while (i < m && j < n) {
		if (nums1[i] <= nums2[j]) {
			mergednums.push_back(nums1[i++]);
		} else {
			mergednums.push_back(nums2[j++]);
		}
	}
	
	while (i < m) {
		mergednums.push_back(nums1[i++]);
	}
	while (j < n) {
		mergednums.push_back(nums2[j++]);
	}
	
	sort(mergednums.begin(), mergednums.end());
	
	for (int num : mergednums) {
		cout << num << " ";
	}	
	return true;
}

int main() {
	vector<int> nums1, nums2;
	vector<int>::size_type m, n;
	cin >> m >> n;

    if (m == 0 || n ==0){
		cerr << "error";
		return 1;
	}
	
	int num;
	for (vector<int>::size_type i = 0; i < m; ++i) {
		cin >> num;
		nums1.push_back(num);
	}

	for (vector<int>::size_type i = 0; i < n; ++i) {
		cin >> num;
		nums2.push_back(num);
	}
	
	mergeNums(nums1, nums2, m, n);
	
	return 0;
}

 鸡兔同笼问题

题目描述

"鸡兔同笼"是一个经典的数学问题,起源于中国的《算经》一书。问题的描述是这样的:一个笼子里面关着一些鸡和兔子(鸡有两只脚,兔子有四只脚)。如果我们数头有a个,数脚有b个,那么如何确定笼子里面有多少只鸡和多少只兔子?

输入:两个整数,分别表示头数和脚数

输出:鸡的个数和兔子的个数

 

样例输入输出

样例1

输入:

4 12

输出:

2 2

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
	int headnum, footnum;
	cin >> headnum >> footnum;
	if (headnum <= 0 || footnum <= 0) return -1;
	
	cout << (4*headnum-footnum)/2 << " " << (footnum-2*headnum)/2;
	return 0;
	
}

消失的数字

题目描述

连续输入多个大于等于0的数并用空格隔开,将其保存为一个数组,假设的数组中最大的数为n,找出[0,n]这个范围内没有出现在数组中的所有数并列出。

 

样例输入输出

样例1

输入:

0 2

输出:

1

样例2

输入:

9 6 4 2 3 5 7 0 1

输出:

8

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
	vector<bool> existnumflag(10001, false); 
	int num, maxnum = 0;
	
	while (cin >> num) {
		if(num>10000) return -1;
		if (maxnum <= num) maxnum = num;
		existnumflag[num] = true;
		if (cin.get() == '\n') break;
	}
	

	for (int i = 0; i <= maxnum; ++i) {
		if (!existnumflag[i]) cout << i << " ";
	}
	
	return 0;
}

实现智能指针类

请实现一个智能指针类SmartPointer,要求如下:

1、其是一个模板类,具有类型参数T;

2、具有一个T* ptr和int* ref_count两个数据属性;

3、实现空构造函数、常规构造函数(参数为指针类型)、拷贝构造函数;

4、实现赋值运算符重载,包括同类型以及指针类型的赋值;

5、重载*取内容运算符,重载->调用运算符(重载原型为MyClass* operator->(){ return ptr; }),用于类似指针的调用;

6、实现一个析构函数,用于指针内存的释放:当引用计数==1时,动态释放内存。

为了测试这个智能指针,请再构建一个简单的测试类型TestClass,要求如下:

1、TestClass只有一个智能指针对象数据成员SmartPointer sp;

2、其有一个常规构造函数,接受一个智能指针对象作为参数,用于初始化sp;

3、其有一个拷贝构造函数和一个赋值运算符重载函数,均使用浅拷贝直接赋值sp;

测试输入输出如下:

输入:输入5个整数,创建一个动态智能指针类型,并存储输入为动态智能指针指向的数组;创建2个动态的TestClass对象,都接受动态智能指针类型的参数,顺序输出这5个整数,然后delete掉创建的2个动态TestClass对象。

输出:顺序输出这5个整数。

 

样例输入输出

样例1

输入:

1 2 3 4 5

输出:

1 2 3 4 5

代码

#include <bits/stdc++.h>
using namespace std;

template<typename T>

class SmartPointer{
private:
    T* ptr;
    int* ref_count;
public:
    //空构造函数
    SmartPointer():ptr(nullptr), ref_count(new int(1)) {};
    //常规构造
    SmartPointer(T* _ptr) :ptr(_ptr), ref_count(new int(1)) {};
    SmartPointer(const SmartPointer<T>& other):ptr(other.ptr), ref_count(other.ref_count){
        (*ref_count)++;
    }
    SmartPointer<T>& operator=(const SmartPointer<T>& other){
        if(this != &other){
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            (*ref_count)++;
        }
        return *this;

    }
    SmartPointer<T>& operator=(T*p){
        release();
        ptr = p;
        ref_count = new int(1);
        return *this;
    }
    T& operator*(){
        return *ptr;
    }
    T& operator->(){
        return ptr;
    }
    T& operator[](int index){
        return ptr[index];
    }
    ~SmartPointer(){
        release();
    }
private:
    void release(){
        if(this->ref_count!=nullptr){
            (*this->ref_count)--;
            if(*this->ref_count == 0){
                delete this->ptr;
                delete this->ref_count;
                this->ptr = nullptr;
                this->ref_count = nullptr;
            }
        }
    }

};


class TestClass{
public:
    SmartPointer<int> sp;

    TestClass(SmartPointer<int> sp_): sp(sp_){}
    TestClass(const TestClass& other): sp(other.sp){}
    TestClass& operator=(const TestClass& other) {
        if(this != &other)  
            sp = other.sp;
        return *this;
    }
    void print(){
        for(int i = 0; i < 4; ++i){
            cout << sp[i] << " ";
        }
        cout << sp[4];

    }
};


int main() {
    int size = 5;
    int* arr = new int[size];
    for(int i = 0; i < size; ++i){
        cin >> arr[i];
    }

    SmartPointer<int> sp(arr);
    TestClass *tc1 = new TestClass(sp);
    TestClass *tc2(tc1);
    (*tc1).print();

    delete tc1;
    delete tc2;
    return 0;
}

标准类库:实现智能指针2

请实现一个智能指针类 SmartPointer ,要求如下:
1 、其是一个模板类,具有类型参数 T
2 、具有一个 T* ptr int* ref_count 两个数据属性;
3 、实现空构造函数、常规构造函数(参数为指针类型)、拷贝构造函数;
4 、实现赋值运算符重载,包括同类型以及指针类型的赋值;
5 、重载 * 取内容运算符,重载 -> 调用运算符(重载原型为 MyClass* operator->(){ return ptr; } ),
用于类似指针的调用;
6 、实现一个析构函数,用于指针内存的释放:当引用计数 ==1 时,动态释放内存。
为了测试这个智能指针,请再构建一个简单的测试类型 TestClass , 要求如下:
1 TestClass 只有一个智能指针对象数据成员 SmartPointer<T> sp ;
2 、其有一个常规构造函数,接受一个智能指针对象作为参数,用于初始化 sp ;
3 、其有一个拷贝构造函数和一个赋值运算符重载函数,均使用浅拷贝直接赋值 sp

样例输入输出

样例1

输入:

3
1 2 3

输出:

SmartPointer Constructor
create a new smart pointer
SmartPointer Constructor
increase ref_count[1] by 1
SmartPointer Constructor
increase ref_count[2] by 1
Deconstructor
decrease ref_count [3] by 1
SmartPointer Constructor
increase ref_count[2] by 1
SmartPointer Constructor
increase ref_count[3] by 1
Deconstructor
decrease ref_count [4] by 1
SmartPointer Constructor
increase ref_count[3] by 1
SmartPointer Constructor
increase ref_count[4] by 1
Deconstructor
decrease ref_count [5] by 1
Assignment Operator
decrease ref_count [4] by 1
increase ref_count[3] by 1
Assignment Operator
decrease ref_count [4] by 1
increase ref_count[3] by 1
Deconstructor
decrease ref_count [4] by 1
Deconstructor
decrease ref_count [3] by 1
Deconstructor
decrease ref_count [2] by 1
Deconstructor
decrease ref_count [1] by 1

样例2

输入:

1
2

输出:

SmartPointer Constructor
create a new smart pointer
SmartPointer Constructor
increase ref_count[1] by 1
SmartPointer Constructor
increase ref_count[2] by 1
Deconstructor
decrease ref_count [3] by 1
Deconstructor
decrease ref_count [2] by 1
Deconstructor
decrease ref_count [1] by 1

代码

#include <iostream>
using namespace std;

template<typename T>
class SmartPointer {
private:
    T* ptr;              // 指向动态分配的对象的指针
    int* ref_count;     // 引用计数指针

public:
    // 空构造函数
    SmartPointer() : ptr(nullptr), ref_count(nullptr) {}

    // 常规构造函数
    explicit SmartPointer(T* p) : ptr(p), ref_count(new int(1)) {
        cout<<"SmartPointer Constructor"<<endl;
        cout<<"create a new smart pointer"<<endl;
    }

    // 拷贝构造函数
    SmartPointer(const SmartPointer<T>& other) : ptr(other.ptr), ref_count(other.ref_count) {
        cout<<"SmartPointer Constructor"<<endl;
        if (ptr) {
            cout<<"increase ref_count["<<*ref_count<<"] by 1"<<endl;
            (*ref_count)++;
        }
    }

    // 赋值运算符重载
    SmartPointer<T>& operator=(const SmartPointer<T>& other) {
        cout<<"Assignment Operator"<<endl;
        if (this != &other) {
            // 减少当前对象的引用计数,并在适当时释放资源
            if (ptr) {
                cout<<"decrease ref_count ["<<*ref_count<<"] by 1"<<endl;
                (*ref_count) --;
                if(!(*ref_count)){
                    delete ptr;
                    delete ref_count;
                }
            }

            // 复制新的指针和引用计数
            ptr = other.ptr;
            ref_count = other.ref_count;
            if (ptr) {
                cout<<"increase ref_count["<<*ref_count<<"] by 1"<<endl;
                (*ref_count)++;
            }
        }
        return *this;
    }

    // 赋值运算符重载(指针类型)
    SmartPointer<T>& operator=(T* newPtr) {
        cout<<"Assignment Operator"<<endl;
        if (ptr != newPtr) {
            // 减少当前对象的引用计数,并在适当时释放资源
            if (ptr) {
                cout<<"decrease ref_count ["<<*ref_count<<"] by 1"<<endl;
                (*ref_count) --;
                if(*ref_count == 0){
                    delete ptr;
                    delete ref_count;
                }
            }

            // 复制新的指针
            ptr = newPtr;
            // 初始化新的引用计数
            ref_count = new int(1);

            cout<<"create a new smart pointer"<<endl;
        }
        return *this;
    }

    // 重载*运算符
    T& operator*() const { return *ptr; }
    T& operator[](int i) const { return ptr[i]; }

    // 重载->运算符
    T* operator->() const { return ptr; }

    // 析构函数
    ~SmartPointer() {
        cout<<"Deconstructor"<<endl;
        if (ptr) {
            cout<<"decrease ref_count ["<<*ref_count<<"] by 1"<<endl;
            (*ref_count) --;
            if(!(*ref_count)){
                delete ptr;
                delete ref_count;
            }
        }
    }
};

template<typename T>
class TestClass {
public:
    SmartPointer<T> sp;  // 智能指针数据成员
    // 常规构造函数
    TestClass(SmartPointer<T> p) : sp(p) {}

    // 拷贝构造函数
    TestClass(const TestClass& other) : sp(other.sp) {}

    // 赋值运算符重载
    TestClass& operator=(const TestClass& other) {
        if (this != &other) {
            sp = other.sp;
        }
        return *this;
    }
};

int main() {
    int n;
    cin>>n;
    
    SmartPointer<int> p = SmartPointer<int>(new int[n]);
    for (int i = 0; i < n; ++i) {
        int m;
        cin>>m;
        p[i] = m;
    }

    TestClass<int>* TCPtr[10];
    for (int i = 0; i < n; ++i) {
        TCPtr[i] = new TestClass<int>(p);
        TCPtr[i]->sp[i] *= i;  
    }

    for (int i = 1; i < n; ++i) {
        *TCPtr[i] = *TCPtr[i-1];
        TCPtr[i]->sp[i] *= i*(i-1);  
    }

    for (int i = 0; i < n; ++i) {
        delete TCPtr[i];
        TCPtr[i] = nullptr;
    }

    return 0;
}

链表:压缩的字符串表示

题目描述

在存储大量字符串数据的时候,由于字符串中存在重复的字串,存储重复的字串会导致多份的内存占用。

请你用数组或者链表实现一个压缩的字符串表示,其想法是通过在一个大型字符串中共享重复字串来降低重复字符的重复存储。

现在给你一个长字符串,你需要找出该字符串中的总共重复次数大于2且字符数长度大于2个字符的重复字符,将其单独提取出来表示为共享的字符串,

然后在主字符串中对应的位置填上特殊符号‘^’标记该字符串为共享字符串,然后下一个8位存储其共享子串的在数组或者链表中的位置,以此类推。

替换的策略为总是优先替换最长的重复字符串,如果两个重复字符串的长度相同则选择重复次数最多的字符串进行替换,如果长度和次数均一样,则按照ASCII字典序从小到大获取最小字典序的子串(string类型比大小)。

输入:输入一个长的字符串(可以包含空格)

输出:按搜索到的替换顺序每行输出共享的字串、重复次数以及替换id(按字符串长度和重复次数排序),倒数第二行输出压缩后的字符串,最后一行输出压缩前后字符串的字符数量,以/隔开

 

样例输入输出

样例1

输入:

hhhhahhhhahhhhahhhahhhhahhhaaahahaaah

输出:

hhhahhhhahhh:2:0
aaah:2:1
Compressed string: h^0ha^0^1ah^1
Compressed ratio: 37/13

样例2

输入:

a0a11a11a2a3a4a5a6a7a8a9

输出:

11a:2:0
Compressed string: a0a^0^02a3a4a5a6a7a8a9
Compressed ratio: 24/22

 代码

#include <bits/stdc++.h>
using namespace std;

// 查找所有重复次数大于2并且在原始字符中总重复字符数大于9的最长重复子串 
void findAllRepeatedSubstrings(const string& input, vector<string>& repeatedSubstrings, vector<int>& repetitionCounts) {
    int n = input.length();
    for (int i = 0; i < n; ++i) {
        if (input[i] == '^') continue;
        for (int j = i + 1; j < n; ++j) {
            string substring = input.substr(i, j - i);
            if (substring.back() == '^') break;
            int count = 1;
            for (int k = i + substring.length(); k <= n - substring.length(); ++k) {
                if (input.substr(k, substring.length()) == substring) {
                    ++count;
                }
            }
            if (count >= 2 && substring.length() > 2) {
                bool alreadyExists = false;
                for (int l = 0; l < repeatedSubstrings.size(); ++l) {
                    if (repeatedSubstrings[l] == substring) {
                        alreadyExists = true;
                        repetitionCounts[l] += count;
                        break;
                    }
                }
                if (!alreadyExists) {
                    repeatedSubstrings.push_back(substring);
                    repetitionCounts.push_back(count);
                }
            }
        }
    }
}

// 实现一个函数findMostLengthRepeatedSubstrings查找字符串中最长的重复字串(至少重复2次),并且返回重复字符串以及重复次数
pair<string, int> findMostLengthRepeatedSubstrings(const string& input) {
    vector<string> repeatedSubstrings;
    vector<int> repetitionCounts;
    findAllRepeatedSubstrings(input, repeatedSubstrings, repetitionCounts);
    int maxLength = 0;
    int maxIndex = -1;
    string maxString = "";
    for (int i = 0; i < repeatedSubstrings.size(); ++i) {
        if (repeatedSubstrings[i].length() > maxLength) {
            maxLength = repeatedSubstrings[i].length();
            maxIndex = i;
            maxString = repeatedSubstrings[i];
        } else if (repeatedSubstrings[i].length() == maxLength) {
            if (repetitionCounts[i] > repetitionCounts[maxIndex] || 
                (repetitionCounts[i] == repetitionCounts[maxIndex] && repeatedSubstrings[i] < maxString)) {
                maxIndex = i;
                maxString = repeatedSubstrings[i];
            }
        }
    }
    if (maxIndex != -1) {
        return {repeatedSubstrings[maxIndex], repetitionCounts[maxIndex]};
    } else {
        return {"", 0};
    }
}

// 查找所有重复子串及其重复次数
void findRepeatedSubstrings(const string& input, vector<string>& repeatedSubstrings, vector<int>& repetitionCounts) {
    string search_input = input;
    while (true) {
        pair<string, int> tmp = findMostLengthRepeatedSubstrings(search_input);
        string repeatedSubstring = tmp.first;
        int repetitionCount = tmp.second;
        if (repeatedSubstring.empty() || repetitionCount == 0) break;
        repeatedSubstrings.push_back(repeatedSubstring);
        repetitionCounts.push_back(repetitionCount);
        string replacement = "^";
        size_t pos = search_input.find(repeatedSubstring);
        while (pos != string::npos) {
            search_input.replace(pos, repeatedSubstring.length(), replacement);
            pos = search_input.find(repeatedSubstring, pos + replacement.length());
        }
    }
}

// 压缩字符串
string compressString(const string& input) {
    vector<string> repeatedSubstrings;
    vector<int> repetitionCounts;
    findRepeatedSubstrings(input, repeatedSubstrings, repetitionCounts);
    string compressedString = input;
    for (int i = 0; i < repeatedSubstrings.size(); ++i) {
        cout << repeatedSubstrings[i] << ":" << repetitionCounts[i] << ":" << i << endl;
        string replacement = "^" + to_string(i);
        size_t pos = compressedString.find(repeatedSubstrings[i]);
        while (pos != string::npos) {
            compressedString.replace(pos, repeatedSubstrings[i].length(), replacement);
            pos = compressedString.find(repeatedSubstrings[i], pos + replacement.length());
        }
    }
    return compressedString;
}

int main() {
    string input;
    getline(cin, input);
    string compressedString = compressString(input);
    cout << "Compressed string: " << compressedString << endl;
    cout << "Compressed ratio: " << input.length() << "/" << compressedString.length() << endl;
    return 0;
}

交换礼物

题目描述

幼儿园有n个小朋友在互相交换礼物,他们各自的不同数量的同一种礼物,现在他们需要和不同的小朋友互相交换礼物。

输入:
第一行输入n表示有n个小朋友
接下来的n行,每行输入一个字符串表示小朋友名字,一个整数m(0<=m<=n-1)表示礼物数量,一个字符串表示小朋友拥有的礼物名称(初始所有人只有同一种类的礼物),连续m个整数表示想要交换的人,每次交换只会送出自己拥有的一个礼物(比如第一次送出一个后还剩m-1个)并收获来自别人的另外一个礼物,收到的礼物不会再送出。如果存在互相都想交换的情况,则只需要交换一次,比如a的交换列表中有b而b中有a,则只需要交换一次。如果最后小朋友想要交换的礼物不够了则停止交换。

输出:输出n行,每行输出小朋友的名子,以及多个礼物和整数的对,表示小朋友交换完成之后的拥有的礼物以及数量

注意:你需要分别将礼物和小朋友构造为结构体,将交换礼物操作实现为一个swap函数。每个小朋友拥有m个初始的礼物,每次将会交换出去一个礼物。

 

样例输入输出

样例2

输入:

4
a 3 aaaa 1 2 3
b 2 bbbb 0 3
c 3 cccc 0 1 3
d 2 dddd 1 2

输出:

a bbbb: 1 cccc: 1 dddd: 1
b aaaa: 1 dddd: 1
c cccc: 2 aaaa: 1
d aaaa: 1 bbbb: 1

样例3

输入:

2
bob 1 banana 1
jim 1 orange 0

输出:

bob orange: 1
jim banana: 1

样例3

输入:

5
a 4 aaaaa 1 2 3 4
b 3 bbbbb 0 2 3  
c 2 ccccc 3 4 
d 1 ddddd 0
e 1 ddddd 3

输出:

a bbbbb: 1 ccccc: 1 ddddd: 2
b bbbbb: 1 aaaaa: 1 ccccc: 1
c aaaaa: 1 bbbbb: 1
d aaaaa: 1
e aaaaa: 1

样例4

输入:

2
jim 1 banana 0  
bob 1 orange 1  

输出:

jim banana: 1
bob orange: 1

样例5

输入:

2
jim 1 banana 0  
bob 1 orange 0  

输出:

jim orange: 1
bob banana: 1

 代码

#include <bits/stdc++.h>
using namespace std;

// 礼物结构体
struct Gift {
    string name;    // 礼物名称
    int quantity;   // 礼物数量
};

// 小朋友结构体
struct Child {
    int id;                         // 小朋友ID
    string name;                    // 小朋友姓名
    vector<int> exchangeList;       // 交换列表,记录想要与之交换礼物的小朋友的ID
    vector<Gift> gifts;             // 礼物列表,记录小朋友拥有的礼物
};

// 交换礼物函数
void swapGifts(Child& child1, Child& child2) {
    bool child1_has_the_gift = false, child2_has_the_gift = false;

    // 判断child1是否拥有child2的礼物
    for (auto& gift : child1.gifts) {
        if (child2.gifts[0].name == gift.name) {
            gift.quantity++;        // 礼物数量加1
            child1_has_the_gift = true;
            break;
        }
    }

    // 如果child1没有child2的礼物,则将child2的礼物加入child1的礼物列表
    if (!child1_has_the_gift) {
        Gift child2_gift = child2.gifts[0];
        child2_gift.quantity = 1;
        child1.gifts.push_back(child2_gift);
    }

    // 判断child2是否拥有child1的礼物
    for (auto& gift : child2.gifts) {
        if (child1.gifts[0].name == gift.name) {
            gift.quantity++;        // 礼物数量加1
            child2_has_the_gift = true;
            break;
        }
    }

    // 如果child2没有child1的礼物,则将child1的礼物加入child2的礼物列表
    if (!child2_has_the_gift) {
        Gift child1_gift = child1.gifts[0];
        child1_gift.quantity = 1;
        child2.gifts.push_back(child1_gift);
    }

    // 减少child1和child2原有礼物的数量
    child1.gifts[0].quantity--;
    child2.gifts[0].quantity--;

    // 如果child1也在child2想要交换礼物的列表里,则将child1从child2的交换列表中去掉
    for (int i = 0; i < child2.exchangeList.size(); i++) {
        if (child2.exchangeList[i] == child1.id) {
            child2.exchangeList.erase(child2.exchangeList.begin() + i);
            break;
        }
    }
}

int main() {
    int n;
    cin >> n;

    vector<Child> children;

    // 输入小朋友信息
    for (int i = 0; i < n; i++) {
        string name;
        int quantity;
        string giftName;
        cin >> name >> quantity >> giftName;

        vector<int> exchangeList(quantity);
        for (int j = 0; j < quantity; j++) {
            cin >> exchangeList[j];
        }
        vector<Gift> giftList(1, {giftName, quantity});

        Child child = {i, name, exchangeList, giftList};
        children.push_back(child);
    }

    // 根据交换列表进行礼物交换
    for (auto& child : children) {
        for (int exchangeIndex : child.exchangeList) {
            if (exchangeIndex != child.id && child.gifts[0].quantity > 0 && children[exchangeIndex].gifts[0].quantity > 0) {
                swapGifts(child, children[exchangeIndex]);
            }
        }
    }

    // 输出每个小朋友的礼物情况
    for (const auto& child : children) {
        cout << child.name << " ";
        for (const auto& gift : child.gifts) {
            if (gift.quantity == 0) continue;
            cout << gift.name << ": " << gift.quantity;
            if (&gift != &child.gifts.back()) 
                cout << " ";
        }
        if (&child != &children.back())
            cout << endl;
    }

    return 0;
}

浮点数组排序

题目描述

输入一个整数n(10^9>n>0),以随机种子0,随机生成包含n个float类型值的数组,对数组从小到大进行排序,然后输出最小前10个数,n<10则输出前n个数。

输入:一个整数n

输出:多行浮点数

 

样例输入输出

样例1

输入:

2

输出:

0.548814
0.592845

代码 

#include <iostream>
#include <random>
#include <algorithm>
using namespace std;
int main() {
std::mt19937 generator(0);
int n;
cin >> n;
float arr[n];
uniform_real_distribution<float> distribution(0.0, 1.0);
for (int i = 0; i < n; ++i){
    arr[i] = distribution(generator);
    }
    sort(arr, arr + n);

    int output_count = min(n, 10);
    for (int i = 0; i < output_count; ++i) {
        cout << arr[i] << endl;
    }

return 0;
}

数组排序

题目描述

请输入n个整数,并将其存储到一个连续数组中,然后对数组进行排序,将排序后的数据按从小到大的数据输出。

输入:按空格隔开的连续n个整数

输出:从小到大排好序的n个整数

 

样例输入输出

样例1

输入:

5 1 2 3 4

输出:

1 2 3 4 5

代码 

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
    int arr[100]; 
    int n = 0;
    int num;
 
    while (cin >> num) {
        arr[n++] = num;
    if ( cin.get() =='\n')
        break;
    }

    sort(arr, arr+n);

    for (int i = 0; i < n; ++i) {
        cout << arr[i] << " ";
    }

    return 0;
}

 结构体的内部空间探索

题目描述

理解结构体和class在内存中的编码和存储方式。定义一个struct结构体,其包含1个int、2个char、1个float、1个char、1个double、1个int、1个char的数据。首先按照定义顺序输入对应的7个值,然后在第一行顺序输出结构体中的每个成员的值;第二行计算并输出每个成员相对于第一个数据成员地址的相对偏移字节数(第一个成员的相对偏移为0字节,第二个为4,手动计算该静态偏移值);第三行根据相对地址偏移来获取每个数据成员的首地址,然后根据该首地址获取每一个数据成员的值然后输出(验证手动计算的偏移值是否正确);第四行输出该结构体的占用内存大小(sizeof)。

 

样例输入输出

样例1

输入:

1 a b 3.14 c 5.27 2 d

输出:

1 a b 3.14 c 5.27 2 d
0 4 5 8 12 16 24 28
1 a b 3.14 c 5.27 2 d
32

代码

#include <iostream>
using namespace std;

struct MyStruct {
    int a;
    char b;
    char c;
    float d;
    char e;
    double f;
    int g;
    char h;
};

int main() {
    MyStruct myStruct;

    cin >> myStruct.a >> myStruct.b >> myStruct.c >> myStruct.d >> myStruct.e >> myStruct.f >> myStruct.g >> myStruct.h;
    cout << myStruct.a << " " << myStruct.b << " " << myStruct.c << " " << myStruct.d << " " << myStruct.e << " " << myStruct.f << " " << myStruct.g << " " << myStruct.h << endl;
    cout << "0 " << sizeof(myStruct.a) << " " << offsetof(MyStruct, c) << " " << offsetof(MyStruct, d) << " " << offsetof(MyStruct, e) << " " << offsetof(MyStruct, f) << " " << offsetof(MyStruct, g) << " " << offsetof(MyStruct, h) << endl;
    char* baseAddress = reinterpret_cast<char*>(&myStruct);
    cout << *reinterpret_cast<int*>(baseAddress + offsetof(MyStruct, a)) << " "
        << *reinterpret_cast<char*>(baseAddress + offsetof(MyStruct, b)) << " "
        << *reinterpret_cast<char*>(baseAddress + offsetof(MyStruct, c)) << " "
        << *reinterpret_cast<float*>(baseAddress + offsetof(MyStruct, d)) << " "
        << *reinterpret_cast<char*>(baseAddress + offsetof(MyStruct, e)) << " "
        << *reinterpret_cast<double*>(baseAddress + offsetof(MyStruct, f)) << " "
        << *reinterpret_cast<int*>(baseAddress + offsetof(MyStruct, g)) << " "
        << *reinterpret_cast<char*>(baseAddress + offsetof(MyStruct, h)) << endl;
    cout << sizeof(myStruct) << endl;

    return 0;
}

 字符串出现次数统计

题目描述

描述

输入两个字符串str1和str2,问str2在str1中出现了多少次。

输入描述:

输入两个字符串str1和str2

输出描述:

输出一个整数表示str2在str1中的出现次数

 

样例输入输出

样例1

输入:

hello nankai
nankai

输出:

1

样例2

输入:

strstrstr
strstr

输出:

2

代码

#include <iostream>
#include <cstring>
using namespace std;

int countSubstring(const char* fullstr, const char* substr) {
    int fulllength = strlen(fullstr);
    int sublength = strlen(substr);
    int count = 0;
    if (fulllength < sublength || fulllength == 0 || sublength == 0){
        return false;
    }
    else {
        for (int i = 0; i <= fulllength - sublength; ++i) {
        int j;
        for (j = 0; j < sublength; ++j) {
            if (fullstr[i + j] != substr[j]) {
                break;
            }
        }
        if (j == sublength) {
            ++count;
        }
    }

    return count;
    }

}

int main() {
    char fullstr[1000], substr[1000];
    cin.getline(fullstr, 1000);
    cin.getline(substr, 1000);
    
    int counts = countSubstring(fullstr, substr);
    cout << counts << endl;

    return 0;
}

 自定义字符串输出

题目描述

重新定义字符串的输出,在遇到\0时输出$符号,在遇到$符号时则中止输出(不输出$符号)

输入:至少带有一个$符号的字符串

输出:按照要求格式输出字符串

 

样例输入输出

样例1

输入:

hello$world

输出:

hello

代码

#include <bits/stdc++.h>
using namespace std;
int main(){
	char input[1000];
	cin.getline(input, 1000, '$');
	for(int i = 0; input[i] != '\0'; ++i){
		if (input[i] == '$') break;
		cout << input[i];
	}
	return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值