好久不写题, DP 都这么生疏了,想不到复杂度合适的 DP 。。。
题目链接
参考题解
度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同。度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少?
直接将所有价格存入 set 中,然后输出第三小的即可。
刚开始没注意不能相等,直接排序输出,结果没 AC ,仔细看样例后就能理解题目是求所有不同的价格中第三小的。
#include
#include
#include
#include
using namespace std;
int n, a;
set<int> st;
int main() {
while(1 == scanf("%d", &n)) {
st.clear();
for(int i = 0; i < n; ++i) {
scanf("%d", &a);
st.insert(a);
}
if(st.size() < 3) {
printf("-1\n");
}
else {
st.erase(st.begin());
st.erase(st.begin());
printf("%d\n", *st.begin());
}
}
return 0;
}
三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用’R’, ‘G’, ‘B’表示。
现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大。
但是三角形必须满足:三个点的颜色要么全部相同,要么全部不同。
直接枚举颜色全相同的三个点和颜色全部不同的三个点,取面积最大的即可,时间复杂度 O(n3) 。
忘了通过坐标求面积的公式了,只得通过点积推出角度,然后求面积。
#include
#include
#include
#include
using namespace std;
const double EPS = 1e-6;
struct Node {
int x, y, z;
Node() {}
Node(int xx, int yy, int zz): x(xx), y(yy), z(zz) {}
Node operator - (const Node& a) const {
return Node(x - a.x, y - a.y, z - a.z);
}
double operator * (const Node& a) const {
return x * a.x + y * a.y + z * a.z;
}
double length() {
return sqrt(0.0 + x * x + y * y + z * z);
}
}p[3][53];
int n, cnt[3], x, y, z;
char color[3];
double ans;
double getArea(const Node& pa, const Node& pb, const Node& pc) {
Node pab = pb - pa, pac = pc - pa;
double mul = pab.length() * pac.length();
if(fabs(mul) < EPS) {
return 0;
}
return 0.5 * mul * sin(acos((pab * pac) / mul));
}
int main() {
while(1 == scanf("%d", &n)) {
memset(cnt, 0, sizeof(cnt));
while(n-- > 0) {
scanf("%s%d%d%d", color, &x, &y, &z);
if(color[0] == 'R') {
p[0][cnt[0]++] = Node(x, y, z);
}
else if(color[0] == 'G') {
p[1][cnt[1]++] = Node(x, y, z);
}
else {
p[2][cnt[2]++] = Node(x, y, z);
}
}
ans = 0;
//相同颜色
for(int c = 0; c < 3; ++c) {
for(int i = cnt[c] - 1; i >= 0; --i) {
for(int j = i - 1; j >= 0; --j) {
for(int k = j - 1; k >= 0; --k) {
ans = max(ans, getArea(p[c][i], p[c][j], p[c][k]));
}
}
}
}
//不同颜色
for(int i = cnt[0] - 1; i >= 0; --i) {
for(int j = cnt[1] - 1; j >= 0; --j) {
for(int k = cnt[2] - 1; k >= 0; --k) {
ans = max(ans, getArea(p[0][i], p[1][j], p[2][k]));
}
}
}
printf("%.5lf\n", ans);
}
return 0;
}
度度熊有一个N个数的数组,他想将数组从大到小排好序,但是萌萌的度度熊只会下面这个操作:
任取数组中的一个数然后将它放置在数组的最后一个位置。
问最少操作多少次可以使得数组从小到大有序?
这个 DP 没有想到,看了参考题解还是不理解转移方程的意思。。。