从现在开始记录洛谷cpp刷题源码(3)——算法(排序)

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

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

        这是算法章节第一个——模拟与高精度。

        主页有其他章节题目的思路和源码。 从现在开始记录洛谷cpp刷题源码(2)——算法(模拟与高精度)

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

第一题:选举学生会

思路

        这个题就是一个排序算法的适应,可以用最基础的学校教的冒泡排序去完成。冒泡排序就是最小的“往上浮”,最大的“往下坠”。

结果超时了……所以我就改用sort了……

代码

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n, m;
	cin >> n >> m;
	int* num = new int[m];
	//赋值
	for (int i = 0; i < m; i++)
	{
		cin >> num[i];
	}
	sort(num, num+m);
	//输出
	for (int i = 0; i < m; i++)
	{
		cout << num[i] << " ";
	}
}

        这个题sort函数有一个知识点。我最开始用的是vector在创建动态数组,但是sort就不行,所以换用了new来创建。

        然后我去了解了一下,原来是我sort的语法错了,如果用vector的话,就应该是:

   sort(num.begin(), num.end());

第二题:排序

思路

        这个题是一个排序的模版题,所以很简单,按照简单的冒泡去排就行。更简单就是直接用STL库里的sort,但是我这里还是再写一下冒泡排序。

……………………

又超时了。

我很疑惑,我把我的冒泡排序代码放下面,希望有大佬能给予宝贵的意见!

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin >> n;
	int* num = new int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> num[i];
	}
	int temp = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			if (num[i] > num[j])
			{
				temp = num[i];
				num[i] = num[j];
				num[j] = temp;
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		cout << num[i] << " " ;
	}
}

代码

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	cin >> n;
	int* num = new int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> num[i];
	}
	sort(num, num + n);
	for (int i = 0; i < n; i++)
	{
		cout << num[i] << " " ;
	}
}

第三题:[蓝桥杯 2024 省 Java B] 报数游戏

思路

        这是一个蓝桥杯算法题的简单题,虽然是java赛道,但是我用cpp去解决。难度是入门级别。也很好分析。先把这个数全部算出来然后排序,取第202420242024就可以了。

        这样想,代码也很简单。但是最重要的是这个数太大了,所以很有可能内存会溢出+时间超标。所以需要用二分搜索

代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//写一个容斥原理的函数,主要用于二分法计算数字个数从而缩小范围
long long count(long long x)
{
	//需要减去公因数120
	return x / 20 + x / 24 - x / 120;//除不尽也没没关系,主要用于估算在数值=x是小于x的有多少个数
}
int main()
{
	long long k = 202420242024;
	long long ans;
	//二分法
	//规定left=1,right等于一个非常大的数,然后还有一个中间值mid
	long long left = 1, right = 1e18, mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (count(mid) >= k)
		{
			ans = mid;
			right = mid - 1;
		}
		else left = mid + 1;
	}
	cout << ans << endl;

}

最后答案是:

第四题:[蓝桥杯 2013 省 AB] 错误票据

思路

        这个题最开始我没有读懂题意……看了一下输入和输出格式,大概明白了需要做的:

step1:读入数据并存储。由于每一行数据个数不定,但是可以直接用cin读取然后用getline存储呈一个字符串。同时,需要将这个字符串转化为流的形式赋值给数组:stringstream

step2:排序。用sort函数排序

step3:找出对应的数据。由于是一个等差数列,所以就很容易输出两个不符合等差数列的数字。

代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<limits>
#include<string>
#include<sstream>
using namespace std;

int main()
{
	int n;//第一个表示行数
	cin >> n;
	string line;
	vector<int> m;
	//忽略后面所有从cin中输入的回车符
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
	for (int i = 0; i < n; i++)
	{
		getline(cin, line);
		stringstream ss(line);
		int num;
		while (ss >> num)//将ss输入进num中,如果ss无法被输入进num中(即ss不是个整型),则循环停止
		{
			m.push_back(num);//push_back将num放在m数组的最后一位
		}
	}
	sort(m.begin(), m.end());
	for (int i = 0; i < m.size()-1; i++)
	{
		if (m[i + 1] > m[i] + 1)
		{
			cout << m[i] + 1<<" ";
		}
	}
	for (int i = 0; i < m.size()-1; i++)
	{
		if (m[i + 1] == m[i])
		{
			cout << m[i];
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值