【华为练习题】 求最大凸多边形(高级)
来源:互联网 发布:windows一键web安装包 编辑:程序博客网 时间:2024/05/16 07:16
【华为练习题】 求最大凸多边形(高级)
题目
题目描述:
给定一些点,输出最大面积的凸边形。输出起始点为x轴最左边的点,按照顺时针方向输出,每个点必须是凸边形的顶点(不输出边上或凸边形内的点)。输入第一个数n为坐标点个数,后面依次为n个坐标点的坐标,横坐标在前,不同坐标点用‘;’隔开,相同坐标点的横纵坐标用‘,’隔开。
输入样例:
13;-4,1;-2,3;1,3;2,2;1,4;5,4;6,1;2,-4;-3,-3;1,-1;-2,-2;1,-2;-1,-1
输出样例:
-4,1;-2,3;1,4;5,4;6,1;2,-4;-3,-3
注:
- 输入数据的第一个数为点的数目,然后是分号;再后面就是以分号间隔的点;
- 点的数目最少为3个,最多为65535;
- 该题目和斜率相关。
分析
从横坐标最小的点,斜率为正无限开始,依次寻找下一个坐标点。具体过程为,求出该点与其它所有点的斜率,找到小于当前斜率的前提下能形成最大斜率且横坐标大于等于该点的点。直到找到横坐标最大的点为止。再从该点,斜率为正无限开始,依次寻找下一个坐标点。具体过程为,求出该点与其它所有点的斜率,找到小于当前斜率的前提下能形成最大斜率且横坐标小于等于该点的点。直到找到初始位置为止。
解答
#include <iostream>#include <vector>#include <string>#include <algorithm>using namespace std;struct Point{ Point(int a, int b):x(a),y(b) {}; int x,y;};// 判断字符是否为分隔符inline bool isSperator(char c){ return c == ',' || c == ';';}// 计算斜率inline double computeK(Point p1, Point p2){ double disX = p2.x - p1.x; double disY = p2.y - p1.y; if (disX == 0) { return disY > 0 ? INT_MAX : INT_MIN; } return disY / disX;}// 找到下一个符合条件的坐标点int findNextPoint(const vector<Point> &vp, int now, double &nowK, bool &flag){ if (flag) { int max = now + 1; double maxK = computeK(vp[now],vp[max]); for (unsigned i = now + 2; i < vp.size(); i++) { double k = computeK(vp[now],vp[i]); if (k > maxK && k <= nowK) { max = i; maxK = k; } } nowK = maxK; return max; } else { int max = now - 1; double maxK = computeK(vp[max],vp[now]); for (int i = now - 2; i >= 0; i--) { double k = computeK(vp[i],vp[now]); if (k > maxK && k <= nowK) { max = i; maxK = k; } } nowK = maxK; return max; }}void findPoints(const string &s, vector<Point> &result){ // 将所有数字读入tmp中 vector<int> tmp; auto begin = s.begin(); while (begin != s.end()) { if (isSperator(*begin)) { begin++; continue; } auto ahead = begin + 1; while (ahead != s.end() && !isSperator(*ahead)) { ahead++; } tmp.push_back(stoi(string(begin,ahead))); begin = ahead; } // 根据读入数据依次创建坐标点,并根据横坐标升序排序(横坐标相同则按纵坐标降序排序) vector<Point> vp; for (unsigned i = 1; i < tmp.size() - 1; i+= 2) { Point p(tmp[i],tmp[i + 1]); vp.push_back(p); } sort(vp.begin(),vp.end(),[](const Point &p1, const Point &p2){ return p1.y > p2.y; }); stable_sort(vp.begin(),vp.end(),[](const Point &p1, const Point &p2){ return p1.x < p2.x; }); // 顺势针依次寻找坐标点 bool flag = true; double nowK = INT_MAX; int now = findNextPoint(vp,0,nowK,flag); result.push_back(vp[0]); while (now != 0) { if (now == vp.size() - 1) { flag = false; nowK = INT_MAX; } result.push_back(vp[now]); now = findNextPoint(vp,now,nowK,flag); }}int main(){ string s; vector<Point> result; cin >> s; findPoints(s,result); // 依次打印坐标点 for (unsigned i = 0; i < result.size(); i++) { cout << result[i].x << "," << result[i].y; if (i != result.size()-1) cout << ";"; } cout << endl; return 0;}
1 0
- 【华为练习题】 求最大凸多边形(高级)
- 华为机试题--求最大凸多边形
- 【华为练习题】 闯迷宫(高级)
- poj 3525 求凸多边形的最大内切圆
- [华为机试练习题]56.求子数组的最大和
- 【华为OJ平台练习题】求最大公共子串的个数和元素
- 2016华为机试题目:最大的凸多边形
- [华为机试练习题]40.求车速
- POJ2187Beauty Contest(求凸多边形直径)
- (华为)求最大公共字符串长度,大小写部分
- 华为OJ(求最大连续bit数)
- 【华为练习题】 阿姆斯特朗数(初级)
- 华为组练习题(一)
- 凸多边形间最大距离
- 求凸多边形距离
- [华为机试练习题]11.最大递减数
- 华为上机练习题--求两个数组的总和
- 华为练习题 求字符串最后一个单词的长度
- postgresql的一个简单的sql
- 如何使用Eclipse打开已有工程听语音
- php 使用redis锁限制并发访问类
- Message Flood
- JDK环境搭建心得
- 【华为练习题】 求最大凸多边形(高级)
- 使用Word Embedding构造文本摘要系
- 数据结构实验之图论二:基于邻接表的广度优先搜索遍历
- 【POJ1487】——Single-Player Games(高斯消元)
- CSS3 垂直居中实现方法
- 把金额字符串加千分位
- 图书
- JZOJ4726. 种花
- C#实现用树型列表动态显示菜单,Winform 常用的UI设计