zoukankan      html  css  js  c++  java
  • 计算几何的几道题

    叉积求面积

    hdu2036(模版题):

    http://acm.hdu.edu.cn/showproblem.php?pid=2036

    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 #include<math.h>
     5 using namespace std;
     6 struct node
     7 {
     8     int x,y;
     9 }q[101];
    10 double cross(node a,node b)
    11 {
    12     return a.x*b.y-a.y*b.x;
    13 }
    14 int main()
    15 {
    16     int i,j,k,n;
    17     while(scanf("%d",&n)&&n)
    18     {
    19         double s = 0;
    20         for(i = 1; i <= n ; i++)
    21         scanf("%d%d",&q[i].x,&q[i].y);
    22         for(i = 1 ; i <= n ; i++)
    23         {
    24             if(i<n)
    25             s+=cross(q[i],q[i+1]);
    26             else
    27             s+=cross(q[n],q[1]);
    28         }
    29         if(s<0)
    30         s  = -s;
    31         s = s/2;
    32         printf("%.1lf\n",s);
    33     }
    34     return 0;
    35 }

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=41

    求怎样旋转这个半圆能包围最多的点

    1.到圆心的距离大于半径的点直接排除。
      
    2.以圆心和任意一点确定一有向线段作为半径位置,分别计数该有向线段左边点的个数(nl)和右边点的个数(nr)
     
    重复步骤2直到所有点都被枚举
    过。
    4.枚举过程中出现的最大的nl
    nr就是所求的结果。
    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 using namespace std;
     5 struct node
     6 {
     7     int x,y;
     8 }no[200];
     9 int cross(int x1,int y1,int x2,int y2)
    10 {
    11     return x1*y2-x2*y1;
    12 }
    13 int main()
    14 {
    15     int i,j,k,n,m,x,y,g;
    16     double r;
    17     while(scanf("%d%d%lf",&n,&m,&r)!=EOF)
    18     {
    19         if(r<0)
    20         break;
    21         scanf("%d",&k);
    22         g = 0;
    23         for(i = 1; i <= k ;i++)
    24         {
    25             scanf("%d%d",&x,&y);
    26             if((x-n)*(x-n)+(y-m)*(y-m)<=r*r)//排除到圆心距离大于半径的点
    27             {
    28                 g++;
    29                 no[g].x = x;
    30                 no[g].y = y;
    31             }
    32         }
    33         int max = 0;
    34         for(i = 1; i <= g ; i++)
    35         {
    36             int numl = 0,numr = 0;
    37             for(j = 1; j <= g ; j++)
    38             {
    39                 int d = cross(no[i].x-n,no[i].y-m,no[j].x-n,no[j].y-m);//点乘判断是哪边的点
    40                 if(d==0)
    41                 {
    42                     numl++;
    43                     numr++;
    44                 }
    45                 if(d>0)
    46                 numl++;
    47                 if(d<0)
    48                 numr++;
    49             }
    50             if(numl>max)
    51             max = numl;
    52             if(numr>max)
    53             max = numr;
    54         }
    55         printf("%d\n",max);
    56     }
    57     return 0;
    58 }
    规范相交题目 利用差乘判断相交 不用考虑重点问题
    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 using namespace std;
     5 double eps=0.0000000001;
     6 struct node
     7 {
     8     double x1,x2,y1,y2;
     9 };
    10 double cross(double x1,double x2,double y1,double y2)
    11 {
    12     return x1*y2-x2*y1;
    13 }
    14 int main()
    15 {
    16     int i,j,k,n,m;
    17     node q[101];
    18     while(scanf("%d",&n)&&n)
    19     {
    20         int num = 0;
    21         for(i = 1; i <= n ; i++)
    22         {
    23             scanf("%lf%lf%lf%lf",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2);
    24         }
    25         for(i = 1; i < n; i++)
    26         for(j = i+1 ; j <= n ; j++)
    27         {
    28             double d1 = cross(q[i].x1-q[i].x2,q[i].y1-q[i].y2,q[i].x1-q[j].x1,q[i].y1-q[j].y1);
    29             double d2 = cross(q[i].x1-q[i].x2,q[i].y1-q[i].y2,q[i].x1-q[j].x2,q[i].y1-q[j].y2);
    30             double d3 = cross(q[j].x1-q[j].x2,q[j].y1-q[j].y2,q[j].x1-q[i].x2,q[j].y1-q[i].y2);
    31             double d4 = cross(q[j].x1-q[j].x2,q[j].y1-q[j].y2,q[j].x1-q[i].x1,q[j].y1-q[i].y1);
    32             if(d1*d2<eps&&d3*d4<eps)
    33             num++;
    34         }
    35         printf("%d\n",num);
    36     }
    37     return 0;
    38 }

      http://poj.org/problem?id=2318

    二分查找+点乘判断左右

    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 using namespace std;
     5 struct node
     6 {
     7     int x1,x2;
     8 }q[5001];
     9 int cross(node a,node b)
    10 {
    11     if(a.x1*b.x2-a.x2*b.x1>0)
    12     return 1;
    13     else
    14     return 0;
    15 }
    16 int x1,x2,n,y1,y2;
    17 int judge(int x,int y)
    18 {
    19     int l =0,r = n+1,mid,k;
    20     node a,b;
    21     while(l<r)
    22     {
    23         mid = (l+r)/2;
    24         if(mid==l)
    25         return mid;
    26         a.x1 = q[mid].x1-q[mid].x2;
    27         a.x2 = y1-y2;
    28         b.x1 = x-q[mid].x2;
    29         b.x2 = y-y2;
    30         if(cross(a,b))
    31         r = mid;
    32         else
    33         l = mid;
    34     }
    35     return mid;
    36 }
    37 int num[5010];
    38 int main()
    39 {
    40     int i,j,m,t,x,y;
    41     while(scanf("%d",&n)&&n)
    42     {
    43         memset(num,0,sizeof(num));
    44         scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
    45         for(i = 1; i <= n ; i++)
    46         scanf("%d%d",&q[i].x1,&q[i].x2);
    47         while(m--)
    48         {
    49             scanf("%d%d",&x,&y);
    50             int k = judge(x,y);
    51             num[k]++;
    52         }
    53         for(i = 0 ; i <= n ; i++)
    54         printf("%d: %d\n",i,num[i]);
    55         puts("");
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    数据库原理分析
    数据库常见索引解析(B树,B-树,B+树,B*树,位图索引,Hash索引)
    数据库索引、B树、B+树
    列存储索引
    比较全面的gdb调试命令
    SQLSERVER如何查看索引缺失
    VIM 实现tab标签页及分屏,切换命令
    查看指定spid的脚本当前运行情况和状态
    通过 sysprocesses 简单查询死锁及解决死锁办法
    ASP.NET Core开源地址
  • 原文地址:https://www.cnblogs.com/shangyu/p/2640217.html
Copyright © 2011-2022 走看看