《算法笔记》学习日记——6.8 pair的常见用法详解&6.9 algorithm头文件下的常用函数

6.8 pair的常见用法详解

Codeup Contest ID:100000603

问题 A: 重心在哪里

题目描述
每个人都知道牛顿发现万有引力的故事。自从牛顿发现万有引力后,人们用万有引力理论解决了非常多的问题。不仅如此,我们也知道了每个物体都有自己的重心。
现在,给你三角形三个顶点的坐标,你能计算出三角形的重心吗?
输入
题目包含多组测试数据。第一行输入一个正整数n,表示测试数据的个数,当n=0时,输入结束。
接下来n行,每行包含6个数字x1,y1,x2,y2,x3,y3,表示三角形三个顶点的坐标。
输出
对于每组输入,输出重心的坐标,结果保留1位小数。
样例输入

2
1.0 2.0 3.0 4.0 5.0 2.0
1.0 1.0 4.0 1.0 1.0 5.0
0

样例输出

3.0 2.7
2.0 2.3

思路
这题比较简单,定义三个pair容器p1、p2、p3,用来存放每个点的信息,然后重心坐标就是x = (x1+x2+x3)/3,y = (y1+y2+y3)/3。
代码

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<string>
#include<utility>
#include<iostream>
using namespace std;
int main(){
	int n;
	while(scanf("%d", &n) != EOF){
		if(n==0) break;
		for(int i=0;i<n;i++){
			pair<double, double> p1, p2, p3;
			double x1, y1, x2, y2, x3, y3;
			scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3);
			p1 = make_pair(x1, y1);
			p2 = make_pair(x2, y2);
			p3 = make_pair(x3, y3);
			double x, y;
			x = (p1.first+p2.first+p3.first)/3;
			y = (p1.second+p2.second+p3.second)/3;
			printf("%.1f %.1f\n", x, y);
		}
	}
	return 0;
}

小结

总的来说,pair可以看成是内含两个元素的结构体吧,调用元素的方式也和结构体一样,直接通过点.来调用,在这里提一下,如果想要多个元素,C++11里面有元组tuple,同样的,在上次给的C++ Reference里面可以找到:
<tuple> - C++ Reference
用法和pair稍有不同,有兴趣的读者可以了解一下,记不住就老实用结构体叭hhhh。

6.9 algorithm头文件下的常用函数

Codeup Contest ID:100000604

问题 A: 求最大最小数

题目描述
先输入N,表示数的个数,然后输入N个数,求这N个数的最大值和最小值。N<=10000,输入的数的绝对值不大于106
样例输入

4  
2 0 1 2

样例输出

2 0

思路
这题也是比较简单的,不过在写的过程中要对N=1和N=2的两种情况特判。
如果N≥3的话,那就先用max()和min()算出前两个数的最大值和最小值,再逐位用max()和min()比较即可。
代码

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
const int maxn = 10000;
int a[maxn] = {0};
int main(){
	int N;
	while(scanf("%d", &N) != EOF){
		for(int i=0;i<N;i++) scanf("%d", &a[i]);
		if(N==1) printf("%d %d\n", a[0], a[0]);
		else{
			int MaxNumber = max(a[0], a[1]);
			int MinNumber = min(a[0], a[1]);
			if(N==2) printf("%d %d\n", MaxNumber, MinNumber);
			else{
				for(int i=2;i<N;i++){
					MaxNumber = max(MaxNumber, a[i]);
					MinNumber = min(MinNumber, a[i]);
				}
				printf("%d %d\n", MaxNumber, MinNumber);
			}	
		}
		memset(a, 0, sizeof(a));
	}
	return 0;
}

问题 B: 全排列

题目描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ < ‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2…sk , T = t1t2…tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, …, sp - 1 = tp - 1, sp < tp成立。
注意每组样例输出结束后接一个空行。
样例输入

xyz

样例输出

xyz
xzy
yxz
yzx
zxy
zyx

提示
用STL中的next_permutation会非常简洁。
思路
这题只要和书上一样,以do…while的形式使用next_permutation()函数即可(字符串的话要用迭代器,那么括号里的两个参数分别就是begin()和end())。另外,在头文件里面除了next_permutation()之外还有prev_permutation(),返回的是全排列的上一个序列。
这题容易出现格式错误,因为题目要求每组样例输出结束后还要接一个空行。
代码

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
int main(){
	string tmp;
	while(getline(cin, tmp)){
		do{
			cout<<tmp<<endl;
		}while(next_permutation(tmp.begin(), tmp.end()));
		cout<<endl;
	}
	return 0;
}

问题 C: 数组逆置

题目描述
输入一个字符串,长度小于等于200,然后将数组逆置输出。
输入
测试数据有多组,每组输入一个字符串。
输出
对于每组输入,请输出逆置后的结果。
样例输入

tianqin

样例输出

niqnait

提示
注意输入的字符串可能会有空格。
思路
这题也没什么难度,直接用reverse()函数即可。要注意的是,字符串的话参数需要填写迭代器。
代码

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
int main(){
	string tmp;
	while(getline(cin, tmp)){
		reverse(tmp.begin(), tmp.end());
		cout<<tmp<<endl;
	}
	return 0;
}

小结

<algorithm>头文件里面其实有非常非常多的函数,包括之前在二分这一章节里写的merge()、partition()、binary_search以及two pointers里的lower_bound()、upper_bound()等等,这些在<algorithm>里面都已经为我们写好了,需要的时候直接调用即可。
感兴趣的同学可以继续在C++ Reference中查看<algorithm>中更多的函数,没准就发现了什么宝藏→_→。

发布了54 篇原创文章 · 获赞 27 · 访问量 4983

猜你喜欢

转载自blog.csdn.net/weixin_42257812/article/details/105348908