从现在开始记录洛谷cpp刷题源码

        2025开始准备蓝桥杯,很多刷题笔记直接写在了代码的注释里,但是一个一个文件保存在电脑里太麻烦了,所以将所有我自己已经编译通过的代码放在这个文档里,也当是对自己学习成果的一个记录。

       我的代码就是按照我自己的思路写的,非常简单也方便我自己理解。 如果能够帮助到和我一样没有什么天赋的朋友,当然是更加荣幸之至。

        从函数章节开始

第一题:距离函数

思路

        这道题非常简单,直接封装一个函数,用于算每个边的长度。我把这个函数命名为dis。需要注意的是每个输入参数都是double类型,得到的距离distance也是double类型。第二步,在main函数里调用三次这个函数。

代码

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;

double dis(double x1, double y1,double x2,double y2)
{
	double distance;
	distance = pow((pow(x2 - x1, 2) + pow(y2 - y1, 2)), 0.5);

	return distance;
}
int main()
{
	double x1, y1;
	double x2, y2;
	double x3, y3;
	cin >> x1 >> y1 ;
	cin >> x2 >> y2;
	cin >> x3 >> y3;
	double Cir;
	Cir = dis(x1, y1,x2,y2) + dis(x2, y2,x3,y3) + dis(x3, y3,x1,y1);
	cout <<fixed<< setprecision(2)<<Cir<< endl;
}

(新学了一个,sqrt()为平方根函数,可以代替上面的pow(,0.5)哈。)

第二题:质数筛

思路

        同样,由于是函数专题,我会封装一个函数isPrime来判断是否为质数,为质数的条件是除了1和本身以外没有因数。所以需要遍历从3到\sqrt{n}就可以了(1,2是特殊的质数,同时因为因数的成对性,只需要判断到该数的平方根即可)。

代码

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
 
//判断是否为质数的函数
bool isPrime(int num)
{
	if (num <= 1)return false;
	if (num == 2)return true;
	if (num >= 3&&sqrt(num)>=3)
	{
		for (int i = 2; i <= sqrt(num); i++)
		{
			if (num % i == 0)return false;
		}
        return true;
	}
    if(num>=3&&sqrt(num)<3)
    {
        for(int i=2;i<num;i++)
        {
            if (num % i == 0)return false;
        }
        return true;
    }
}
int main()
{
        int n;
       cin >> n;

        vector<int> numbers(n);//用vector来动态分配number数组,避免n是一个变量引起的程序错误
        for (int i = 0; i < n; ++i) {
            cin >> numbers[i];
        }
        vector<int> primeNumbers;
        for (int num : numbers) {//这里的for循环为了遍历numbers容器里的所有元素
            if (isPrime(num)) {
                primeNumbers.push_back(num);
            }
        }
        for (int prime : primeNumbers) {
            cout << prime << " ";
        }
        return 0;
}

第三题:闰年展示

思路

        这道题其实跟上一道题思路一致。先判断是否是闰年:除以4的余数是否为0,同时如果是世纪年的话,必须要被400整除(第一遍我没有考虑这个条件,相信也有很多小伙伴会忽略);然后将是闰年的数字输出出来。难点是这道题输入的两个数字是年份范围,所以我认为如何处理这个年份范围是关键。

代码

#include<iostream>
using namespace std;
bool isYear(int x)
{
	if (x % 4 == 0 && x % 100 != 0)return true;
	else if (x % 400 == 0)return true;
	else return false;
}
int main()
{
	int x, y;
	int account=0;
	cin >> x>>y;
	for (int i = x; i <= y; i++)
	{
		if (isYear(i))
		{
			account++;
		}
	}
	cout << account << endl;
	for (int i = x; i <= y; i++)
	{
		if (isYear(i))
		{
			cout << i << " ";
		}
	}
}

第四题:歌唱比赛

思路

       需要记录有n名同学参加比赛和有m名评委,如果将这 n*m个数看作是一个n*m的矩阵(也就是二维数组)然后再用一个n行向量存储平均分后输出最大的就很简单了。

代码

#include <iostream>
#include <vector>
#include <algorithm>//排序sort的头文件
#include <iomanip>

using namespace std;

double calculateScore(vector<int>& scores) {
    // 去掉一个最高分和一个最低分
    sort(scores.begin(), scores.end());//排序函数,两个参数first和last,表示需要排序范围的开头和结尾
    scores.erase(scores.begin());  // 去掉最低分,erase函数就是删除函数,里面的参数为需要删除的数字
    scores.pop_back();             // 去掉最高分,pop_back是删除最后一个元素的函数

    // 计算剩下评分的平均值
    double sum = 0;
    for (int score : scores) {
        sum += score;
    }
    return sum / scores.size();
}

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

    double maxScore = 0.0;

    for (int i = 0; i < n; ++i) {
        vector<int> scores(m);
        for (int j = 0; j < m; ++j) {
            cin >> scores[j];
        }

        double score = calculateScore(scores);
        if (score > maxScore) {
            maxScore = score;
        }
    }

    // 输出最高得分,保留两位小数
    cout << fixed << setprecision(2) << maxScore << endl;

    return 0;
}

第五题:计算阶乘

思路

        这个题如果用for和while循环就是非常基础的题型,这里就直接尝试不用循环结构。如果不用循环结构,即可以马上反应过来,这里应该采用递归算法

代码

#include<iostream>
using namespace std;
int jieCheng(int a)
{
	if (a > 1)
	{
		return a * jieCheng(a - 1);//采用递归算法
	}
	else if (a == 1)
	{
		return 1;
	}
}
int main()
{
	int n;
	cin >> n;
	int ans = jieCheng(n);
	cout << ans << endl;
}

第六题:赦免战俘

思路:

        这个题一看数据量是一个正方形,我的第一思路是用二维数组。所以创建一个大小为2^{n}\times 2^{n}的二维数组。第二个问题,应该如何表示左上角的正方形呢?我们知道,数组的编号是从0到n-1的,如果大小为8*8的数组,左上角的正方形就应该是array[0][0]到array[3][3]这组4*4的数据,我在这里考虑直接利用计算机除法向下取整的特点(或者直接用取整函数:floor向下,ceil向上):比如(0+7)\div 2=3.5,但是计算机除法会直接向下取整等于3,刚好是for循环遍历的终点。

        结果不是很好,因为如果n很大,这样就没办法表示,所以我决定采用坐标来表示每个正方形左上角的点,并且用递归的方法使每分成4个正方形就直接处理。

代码:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

void square(vector<vector<int>>& people, int x, int y, int size)
{
    // 递归终止条件:矩阵大小为 1x1
    if (size == 1)
    {
        people[x][y] = 1;
        return;
    }

    // 分成四个小正方形
    int halfsize = size / 2;

    // 赦免左上角的正方形
    for (int i = x; i < x + halfsize; i++)
    {
        for (int j = y; j < y + halfsize; j++)
        {
            people[i][j] = 0;
        }
    }

    // 递归处理剩下的三个正方形
    square(people, x + halfsize, y, halfsize); // 左下角
    square(people, x, y + halfsize, halfsize); // 右上角
    square(people, x + halfsize, y + halfsize, halfsize); // 右下角
}

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

    // 初始化二维动态数组
    int size = 1 << n; // 计算 2^n
    vector<vector<int>> people(size, vector<int>(size, 1));

    // 调用递归函数
    square(people, 0, 0, size);

    // 输出矩阵
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            cout << people[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

        这道题挺有难度的我觉得……

第七题:最厉害的学生

思路:

        感觉这道题和数据库的查询特别像啊……就像是让我们手搓数据库查询逻辑。

        所以这道题同样类似于一个表格:表头有姓名(char)、语文(int)、数学(int)、英语(int)、总分(int)五项。第一步是需要决定这个表的行数。很像结构体的表示啊,元素的数据类型有差别。所以只需要新建一个结构体,初始化这个结构体就可以了。

        然后需要我们计算总分,也就是student.CHN+student.Math+student.Eng,并且比较最大值。

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 定义学生结构体
struct Student 
{
    string name;    // 姓名
    int chinese;    // 语文成绩
    int math;       // 数学成绩
    int english;    // 英语成绩
    int total;      // 总分
};

int main() 
{
    int N;
    cin >> N; // 输入学生人数

    vector<Student> students(N); // 存储学生信息的数组

    // 输入每个学生的信息
    for (int i = 0; i < N; i++)
     {
        cin >> students[i].name >> students[i].chinese >> students[i].math >> students[i].english;
        // 计算总分
        students[i].total = students[i].chinese + students[i].math + students[i].english;
    }

    // 找到总分最高的学生
    int maxIndex = 0; // 假设第一个学生是总分最高的
    for (int i = 1; i < N; i++) 
    {
        if (students[i].total > students[maxIndex].total) 
        {
            maxIndex = i; // 更新总分最高的学生索引
        }
    }

    // 输出总分最高的学生信息
    cout << students[maxIndex].name << " "
         << students[maxIndex].chinese << " "
         << students[maxIndex].math << " "
         << students[maxIndex].english << endl;

    return 0;
}

        后续更新中……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值