鱼C论坛

 找回密码
 立即注册
查看: 3593|回复: 2

[已解决]凸包算法(convex hull)

[复制链接]
发表于 2021-11-9 17:09:13 From FishC Mobile | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我想问如要找很多组的凸包该如何实现, 用C++。谢谢。
例子:
输入
2(要找多少个)
5(第一个有5个坐标)
1 1
1 -1
0  0
-1 -1
-1 1
8(第二个有8个坐标)
1  0
0  1
0  -1
-1  0
2  0
0  2
0  -2
-2  0
输出
4(第一凸包由4个组成)
-1 -1
1 -1
1 1
-1 1
4(第二个凸包由4个组成)
-2  0
0  -2
0  2
2  0
最佳答案
2021-11-12 22:08:10
题解:
  1. #include <bits/stdc++.h>

  2. struct Point{int x, y;};

  3. int orientation(Point p, Point q, Point r)
  4. {
  5.         int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  6.         if (val == 0) return 0;
  7.         return (val > 0)? 1: 2;
  8. }


  9. void convexHull(Point points[], int n)
  10. {
  11.         if (n < 3) return;
  12.         std::vector<Point> hull;
  13.         int l = 0;
  14.         for (size_t i = 1; i < n; i++) if (points[i].x < points[l].x) l = i;
  15.         int p = l, q;
  16.         do
  17.         {
  18.             hull.push_back(points[p]);
  19.                 q = (p+1)%n;
  20.                 for (size_t i = 0; i < n; i++) if (orientation(points[p], points[i], points[q]) == 2) q = i;
  21.                 p = q;

  22.         } while (p != l);
  23.         std::cout << "\nConvex Hull: " << hull.size() << "points" << std::endl;
  24.         for (size_t i = 0; i < hull.size(); i++) std::cout << hull[i].x << ' ' << hull[i].y << std::endl;
  25.         std::cout << std::endl;
  26. }


  27. int main()
  28. {
  29.         int N, T;
  30.         std::cin >> T;
  31.         for(size_t t = 0; t < T; t++){
  32.             std::cin >> N;
  33.             Point points[N];
  34.             for(size_t i = 0; i < N; i++){
  35.                 int x, y;
  36.                 std::cin >> x >> y;
  37.                 points[i].x = x;
  38.                 points[i].y = y;
  39.             }
  40.             int n = sizeof(points)/sizeof(points[0]);
  41.             convexHull(points, n);
  42.         }
  43.        
  44.         return 0;
  45. }
复制代码
输入/输出:
  1. 2
  2. 5
  3. 1 1
  4. 1 -1
  5. 0  0
  6. -1 -1
  7. -1 1

  8. Convex Hull: 4points
  9. -1 -1
  10. 1 -1
  11. 1 1
  12. -1 1

  13. 8
  14. 1  0
  15. 0  1
  16. 0  -1
  17. -1  0
  18. 2  0
  19. 0  2
  20. 0  -2
  21. -2  0

  22. Convex Hull: 4points
  23. -2 0
  24. 0 -2
  25. 2 0
  26. 0 2
复制代码
我知道可以用 using namespace std,但是我比较喜欢不用命名空间
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-11-12 22:08:10 | 显示全部楼层    本楼为最佳答案   
题解:
  1. #include <bits/stdc++.h>

  2. struct Point{int x, y;};

  3. int orientation(Point p, Point q, Point r)
  4. {
  5.         int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  6.         if (val == 0) return 0;
  7.         return (val > 0)? 1: 2;
  8. }


  9. void convexHull(Point points[], int n)
  10. {
  11.         if (n < 3) return;
  12.         std::vector<Point> hull;
  13.         int l = 0;
  14.         for (size_t i = 1; i < n; i++) if (points[i].x < points[l].x) l = i;
  15.         int p = l, q;
  16.         do
  17.         {
  18.             hull.push_back(points[p]);
  19.                 q = (p+1)%n;
  20.                 for (size_t i = 0; i < n; i++) if (orientation(points[p], points[i], points[q]) == 2) q = i;
  21.                 p = q;

  22.         } while (p != l);
  23.         std::cout << "\nConvex Hull: " << hull.size() << "points" << std::endl;
  24.         for (size_t i = 0; i < hull.size(); i++) std::cout << hull[i].x << ' ' << hull[i].y << std::endl;
  25.         std::cout << std::endl;
  26. }


  27. int main()
  28. {
  29.         int N, T;
  30.         std::cin >> T;
  31.         for(size_t t = 0; t < T; t++){
  32.             std::cin >> N;
  33.             Point points[N];
  34.             for(size_t i = 0; i < N; i++){
  35.                 int x, y;
  36.                 std::cin >> x >> y;
  37.                 points[i].x = x;
  38.                 points[i].y = y;
  39.             }
  40.             int n = sizeof(points)/sizeof(points[0]);
  41.             convexHull(points, n);
  42.         }
  43.        
  44.         return 0;
  45. }
复制代码
输入/输出:
  1. 2
  2. 5
  3. 1 1
  4. 1 -1
  5. 0  0
  6. -1 -1
  7. -1 1

  8. Convex Hull: 4points
  9. -1 -1
  10. 1 -1
  11. 1 1
  12. -1 1

  13. 8
  14. 1  0
  15. 0  1
  16. 0  -1
  17. -1  0
  18. 2  0
  19. 0  2
  20. 0  -2
  21. -2  0

  22. Convex Hull: 4points
  23. -2 0
  24. 0 -2
  25. 2 0
  26. 0 2
复制代码
我知道可以用 using namespace std,但是我比较喜欢不用命名空间
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-12 22:18:38 | 显示全部楼层
兄弟,如果解答对你有帮助,请给最佳解答,谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-12 16:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表