算法训练.

一.扩散

题解:

计算点之间的距离,然后对图进行处理即可,这个数据规模较小,因此我使用了floyd,还有最小生成树和二份答案加并查集的写法;

代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
#include<set>
#include <string>
#include<map>

using namespace std;

using ll = long long;
using ull = unsigned long long;
#define up(i, h, n) for (int  i = h; i <= n; i++) 
#define down(i, h, n) for(int  i = h; i >= n; i--)
#define wh(x) while(x--)
#define node struct node
#define it ::iterator
#define Ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
constexpr int MaxN = 200005;
constexpr int MaxM = 10005;
constexpr int mod = 1e9 + 7;
constexpr int inf = 0x7fffffff;
constexpr double value = 1e-10;


int main() {
	int n;
	int x[55], y[55];
	int e[55][55];
	cin >> n;
	up(i, 1, n) {
		cin >> x[i] >> y[i];
	}
	up(i, 1, n) {
		up(j, 1, n) {
			e[i][j] = abs(x[i] - x[j]) + abs(y[i] - y[j]);
		}
	}
	up(k, 1, n) {
		up(i, 1, n) {
			up(j, 1, n) {
				e[i][j] = min(max(e[i][k], e[k][j]), e[i][j]);
			}
		}
	}
	int ans = 0;
	up(i, 1, n) {
		up(j, 1, n) {
			ans = max(ans, e[i][j]);
		}
	}
	cout << int(ceil(ans * 1.0 / 2));
	return 0;
}

二.三分 函数

题解:

三分模版,三分和二分的原理相同,不同的是,三分对于已知的l和r,会有两个三等分点的值mid;不过这里值得注意的是一些差值,需要误差很小;

代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
#include<set>
#include <string>
#include<map>

using namespace std;

using ll = long long;
using ull = unsigned long long;
#define up(i, h, n) for (int  i = h; i <= n; i++) 
#define down(i, h, n) for(int  i = h; i >= n; i--)
#define wh(x) while(x--)
#define node struct node
#define it ::iterator
#define Ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
constexpr int MaxN = 10005;
constexpr int MaxM = 10005;
constexpr int mod = 1e9 + 7;
constexpr int inf = 0x7fffffff;
constexpr double value = 1e-10;

node{
	double a,b,c;
}e[MaxN];
int t, n;

double check(double x) {
	double max1 = e[0].a * x * x + e[0].b * x + e[0].c;
	up(i, 1, n - 1) {
		max1 = max(e[i].a * x * x + e[i].b * x + e[i].c, max1);
	}
	return max1;
}

void slove() {

	cin >> n;
	up(i, 0, n - 1) {
		cin >> e[i].a >> e[i].b >> e[i].c;
	}
	double l = 0, r = 1000;
	while (r-l>value) {
		double mid1 = l + (r - l) / 3.0;
		double mid2 = r - (r - l) / 3.0;
		if (check(mid1) < check(mid2)) r = mid2;
		else l = mid1;
	}
	printf("%.4lf\n", check(l));
	//cout << fixed << setprecision(4) << check(l);
}
int main() {
	
	Ios;
	cin >> t;
	while (t--) {
		slove();
	}
}

三.Queue Sort

题意:

你需要用一种特殊的排序方法对一个长为 n 的数组进行操作。每次操作,你将 a1​ 放在数组中最后一个小于等于它的元素后面(没有就不动)。求这种排序方法是否可以使得数组升序排列?

题解:

当 a1​ 为原始数组中最后一个最小的数时,题目中的操作变得无意义。而此时数组是否升序,取决于原始数组最后一个最小值后的元素是否升序;原始数组最后一个最小值后的元素升序时操作数为这个元素的下标减一,否则无解;

代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
#include<set>
#include <string>
#include<map>

using namespace std;

using ll = long long;
using ull = unsigned long long;
#define up(i, h, n) for (int  i = h; i <= n; i++) 
#define down(i, h, n) for(int  i = h; i >= n; i--)
#define wh(x) while(x--)
#define node struct node
#define it ::iterator
#define Ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
constexpr int MaxN = 200005;
constexpr int MaxM = 10005;
constexpr int mod = 1e9 + 7;
constexpr int inf = 0x7fffffff;
constexpr double value = 1e-10;

int a[MaxN];
void slove() {

	int n;
	cin >> n;
	int mins = 2e9;
	int ans;
	bool flag = true;
	up(i, 1, n) {
		cin >> a[i];
		if (mins > a[i]) {
			mins = a[i];
			ans = i;
		}
	}
	up(i, ans + 1, n - 1) {
		if (a[i] > a[i + 1]) flag = false;
	}
	if (flag)cout << ans - 1 << endl;
	else cout << -1 << endl;
}

int main() {
	
	Ios;
	int t;
	cin >> t;
	while (t--) {
		slove();
	}
}

四.Querying Multiset

题意:

给定一个集合和 Q 次操作,每个操作可能是以下操作之一:

  • 第一个操作给定整数 x,表示将 x 放入集合。

  • 第二个操作给定整数 x,表示将集合的数分别加上 x。

  • 第三个操作将集合最小的数删除。

对于每个第三个操作,输出你删去的数。

题解:

这几个操作主要是操作二,把根里面的每一个元素遍历更新显然不符合时间复杂度要求,考虑如何把操作二变为单点修改;所以我们不难想到,用一个值 ans来表示当前的增加量,这样操作二可以解决;在这种情况下:对于操作一,把 ans 看作后面插入元素所需的减少量,那么插入的数字 x 可以用 q.push(x-ans) 来代替;对于操作三,只需要输出堆里最小元素加上 ans 的值即可;

代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
#include<set>
#include <string>
#include<map>

using namespace std;

using ll = long long;
using ull = unsigned long long;
#define up(i, h, n) for (int  i = h; i <= n; i++) 
#define down(i, h, n) for(int  i = h; i >= n; i--)
#define wh(x) while(x--)
#define node struct node
#define it ::iterator
#define Ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
constexpr int MaxN = 200005;
constexpr int MaxM = 10005;
constexpr int mod = 1e9 + 7;
constexpr int inf = 0x7fffffff;
constexpr double value = 1e-10;

ll ans;
priority_queue<long, vector <long>, greater<long>>q;

void slove() {

	int n;
	cin >> n;
	if (n == 1) {
		ll x;
		cin >> x;
		q.push(x-ans);
	}
	else if (n == 2) {
		ll x;
		cin >> x;
		ans += x;
	}
	else {
		cout << q.top() + ans << endl;
		q.pop();
	}
}
int main() {

	int t;
	cin >> t;
	while (t--) {
		slove();
	}
	return 0;
}
相关推荐
为什么这亚子37 分钟前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
幸运超级加倍~2 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法2 小时前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR2 小时前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer2 小时前
快乐数算法
算法·leetcode·职场和发展
小芒果_012 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_434085902 小时前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法