再学一道算法题:水果忍者

简介: 再学一道算法题:水果忍者

2010年风靡全球的“水果忍者”游戏,想必大家肯定都玩过吧?(没玩过也没关系啦~)在游戏当中,画面里会随机地弹射出一系列的水果与炸弹,玩家尽可能砍掉所有的水果而避免砍中炸弹,就可以完成游戏规定的任务。如果玩家可以一刀砍下画面当中一连串的水果,则会有额外的奖励,如图1所示。
189.jpg
现在假如你是“水果忍者”游戏的玩家,你要做的一件事情就是,将画面当中的水果一刀砍下。这个问题看上去有些复杂,让我们把问题简化一些。我们将游戏世界想象成一个二维的平面。游戏当中的每个水果被简化成一条一条的垂直于水平线的竖直线段。而一刀砍下我们也仅考虑成能否找到一条直线,使之可以穿过所有代表水果的线段。
image.png
如图2所示,其中绿色的垂直线段表示的就是一个一个的水果;灰色的虚线即表示穿过所有线段的某一条直线。可以从上图当中看出,对于这样一组线段的排列,我们是可以找到一刀切开所有水果的方案的。

另外,我们约定,如果某条直线恰好穿过了线段的端点也表示它砍中了这个线段所表示的水果。假如你是这样一个功能的开发者,你要如何来找到一条穿过它们的直线呢?

输入格式:
image.png
输入样例:
5
-30 -52 -84
38 22 -49
-99 -22 -99
48 59 -18
-36 -50 -72
输出样例:
-99 -99 -30 -52

#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>

#define inf 0x7fffffff
#define ll long long
using namespace std;
const int maxn = 1e4 + 10;
int n;
struct node {
    int x, y1, y2;
} fruits[maxn];

struct node2 {
    int x, y;

    node2() : x(), y() {}

    node2(int x, int y) : x(x), y(y) {}

};

int cmp(node a, node b) {
    return a.x < b.x;
}

ll X(node2 a, node2 b) {
    return 1ll * a.x * b.y - 1ll * a.y * b.x;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> fruits[i].x >> fruits[i].y1 >> fruits[i].y2;
    }
    sort(fruits + 1, fruits + n + 1, cmp);
    for (int i = 1; i <= n; i++) {
        node2 t1 = node2(0, -1);
        node2 t2 = node2(0, 1);
        node2 tp;
        for (int j = 1; j <= i; j++) {
            // 寻找斜率最大的下凸
            tp = node2(fruits[i].x - fruits[j].x, fruits[i].y2 - fruits[j].y1);
            if (X(t1, tp) > 0) {
                t1 = tp;
            }
            // 寻找斜率最小的上凸
            tp = node2(fruits[i].x - fruits[j].x, fruits[i].y2 - fruits[j].y2);
            if (X(t2, tp) < 0) {
                t2 = tp;
            }
        }
        for (int j = i + 1; j <= n; j++) {
            // 寻找斜率最大的下凸
            tp = node2(fruits[j].x - fruits[i].x, fruits[j].y2 - fruits[i].y2);
            if (X(t1, tp) > 0) {
                t1 = tp;
            }
            // 寻找斜率最小的上凸
            tp = node2(fruits[j].x - fruits[i].x, fruits[j].y1 - fruits[i].y2);
            if (X(t2, tp) < 0) {
                t2 = tp;
            }
        }
        if (X(t1, t2) >= 0) {
            ;
            break;
        }
    }
    return 0;
}
相关文章
|
7月前
|
算法
【算法专题突破】滑动窗口 - 水果成篮(13)
【算法专题突破】滑动窗口 - 水果成篮(13)
27 0
|
5月前
|
算法 测试技术 C#
C++前缀和算法的应用:摘水果 原理源码测试用例
C++前缀和算法的应用:摘水果 原理源码测试用例
|
7月前
|
存储 算法 索引
【算法挨揍日记】day07——904. 水果成篮、438. 找到字符串中所有字母异位词
题目描述: 你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而,农场的主人设定了
323 0
|
10月前
|
机器学习/深度学习 移动开发 算法
水果识别系统Python+TensorFlow+Django网页界面+深度学习模型+卷积网络算法
水果识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
169 0
|
算法 JavaScript 前端开发
日拱算法,水果成篮问题
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
再学一道算法题: 九宫格输入法
再学一道算法题: 九宫格输入法
|
存储 算法
再学一道算法题:PAT排名汇总 (排序+存储)
再学一道算法题:PAT排名汇总 (排序+存储)
再学一道算法题: 寻找大富翁
再学一道算法题: 寻找大富翁
|
存储 算法
再学一道算法题: 最长连续递增子序列
再学一道算法题: 最长连续递增子序列
再学一道算法题: 朋友(map)
再学一道算法题: 朋友(map)