• 圈水池 nyoj 78 凸包算法


    圈水池

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
     
    描述
    有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)
     
    输入
    第一行输入的是N,代表用N组测试数据(1<=N<=10)
    第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)
    接下来m行代表的是各个供水装置的横纵坐标
    输出
    输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出
    样例输入
    1
    4
    0 0
    1 1
    2 3
    3 0
    
    样例输出
    0 0
    2 3
    3 0

    该题可用于凸包算法入门 可查看链接:http://www.cnblogs.com/dream-it-possible/p/8514706.html
    /*
    author:谦智
    圈水池  nyoj 78 凸包算法 
    */
    
    //Graham扫描法  求解凸包问题 
    #include<iostream>
    #include<algorithm> 
    using namespace std;
    const int N = 105;
    struct Node{
      int x,y;
      Node() {}
      Node(int x,int y) {
        this->x = x;
        this->y = y;
      }
    };
    Node st[N];
    struct cmp{//将所有的点坐标按照x从小到大排序  x相等时按照y从小到大排序 
      bool operator()(const Node& a,const Node& b) {
        if (a.x != b.x) return a.x < b.x;
        return a.y < b.y;
      }
    };
    int cross(Node a,Node b,Node c) {

    //求向量ab和向量ac的叉积 如果结果为正则ab向量转到ac向量上通过逆时针(转的角度为小角) ==》c点在ab的左侧 ==》c相对于 a 的幅角 α 大于 b相对于 a 的幅角 α return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } long long dist(Node a,Node b) {//计算两点之间的距离的平方 用于比较故不用求出实际的距离 return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y); } bool cmp1(const Node& a,const Node& b) {// 相对于 st[0] 的幅角 α从小到大排序 int m = cross(st[0],a,b); if (m > 0) return 1; if (m == 0 && dist(st[0],a) <= dist(st[0],a)) return 1; return 0; } int main() { int t; cin >> t; Node node[105]; while (t--) { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> node[i].x >> node[i].y; } sort(node,node+n,cmp()); int x1,y1,x2,y2; st[0] = node[0]; sort(node+1,node+n,cmp1); st[1] = node[1]; int top = 1; for (int i = 2; i < n; i++) { while (top > 0 && cross(st[top-1],st[top],node[i]) < 0) { top--; } st[++top] = node[i]; } sort(st,st+top+1,cmp()); for (int i = 0; i <= top; i++) { cout << st[i].x << " "<< st[i].y << endl; } } } //用递归算法求出凸包问题 wa //#include<iostream> //#include<algorithm> //using namespace std; //struct Node{ // int x,y; // Node() {} // Node(int x,int y) { // this->x = x; // this->y = y; // } //}; //struct cmp{ // bool operator()(const Node& a,const Node& b) { // if (a.x != b.x) return a.x < b.x; // return a.y < b.y; // } //}; //int cut; //Node ans[105]; //void getAnsArr(Node node[],int n,int x1,int y1,int x2,int y2) ; //int main() { // int t; // cin >> t; // Node node[105]; // while (t--) { // int n; // cin >> n; // for (int i = 0; i < n; i++) { // cin >> node[i].x >> node[i].y; // } // sort(node,node+n,cmp()); // int x1,y1, x2,y2; // x1 = node[0].x; // y1 = node[0].y; // x2 = node[n-1].x; // y2 = node[n-1].y; // ans[0] = Node(x1,y1); // ans[1] = Node(x2,y2); // cut = 2; // getAnsArr(node,n,x1,y1,x2,y2); // sort(ans,ans+cut,cmp()); // for (int i = 0; i < cut; i++) { // cout << ans[i].x << " " << ans[i].y << endl; // } // } //} //void getAnsArr(Node node[],int n,int x1,int y1,int x2,int y2) { // int x3,y3, count = 0; // if (n <= 1) return ; // x3 = node[0].x; // y3 = node[0].y; // Node temp[105]; // int l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3; // int lMax = l; // int k = 0; // for (int i = 1; i < n; i++) { // x3 = node[i].x; // y3 = node[i].y; // l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3; // if (l >= 0) { // temp[count++] = node[i]; // } // if (l > lMax) { // lMax = l; // k = i; // } // } // if (lMax <= 0) { // for (int i = 0; i < count; i++) { // x3 = temp[i].x; // y3 = temp[i].y; // l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3; // if (l == 0 && !((x3==x2&&y3==y2)||(x3==x1&&y3==y1)) ) { // ans[cut++] = temp[i]; // } // } // return ; // } else { // ans[cut++] = node[k]; // if (count == 0) return ; // } // getAnsArr(temp,count,x1,y1,node[k].x,node[k].y); // getAnsArr(temp,count,node[k].x,node[k].y,x2,y2); //}
     
  • 相关阅读:
    【转】MFC中png格式图片贴图的实现
    【转】Windows 中不规则窗体的编程实现
    【转】MFC添加背景图片方法的三种方法
    【转】mfc win7获得管理员权限 使用WIN7风格 使用当前系统风格
    【转】双缓冲讲解及界面贴图
    【转】[内核/驱动]驱动中获取进程全路径和注册表全路径
    【转】Visual C++中DDB与DIB位图编程全攻略(转)
    【转】vs2010中添加splashScreen
    【转】一个在内存里搜索QQ号码的源码,源自看雪论坛
    输出JSON
  • 原文地址:https://www.cnblogs.com/dream-it-possible/p/8514759.html
Copyright © 2020-2023  润新知