zoukankan      html  css  js  c++  java
  • LA3263 一笔画

    题目大意:
    依次给定多个点(要求第一个点和最后一个点重叠),把前后两个点相连求最后得到的图形的面的个数

    根据欧拉定理:

    设平面图的顶点数为V,边数为E,面数为F,则V+F-E = 2

    这里的E是指如果一条直线上被多个点分割,那么就算多条边

    所以我们要求出V和E的值

    先求点,已给定的点数,还要包括相连过程中相交得到的点,经过去重得到最后的点数

    for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    //if(i==j) continue;
                    if(onIntersection(po[i],po[i+1],po[j],po[j+1])){
                        vp.push_back(getLineIntersection(po[i],po[i+1]-po[i],po[j],po[j+1]-po[j]));
                    }
                }
            }
            sort(vp.begin(),vp.end());
            c=unique(vp.begin(),vp.end()) - vp.begin(); //去重前要先进行排序,unique是对地址进行操作,所以这里使用数组也可以

    然后找边,根据是否有新得到的点出现在边上,若有,每次边数++;

    for(int i=0;i<c;i++){
                for(int j=0;j<n;j++){
                    if(onSegment(vp[i],po[j],po[j+1]))
                        e++;
                }
            }
         

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <cmath>
      5 #include <algorithm>
      6 using namespace std;
      7 #define eps 1e-10
      8 struct Point {
      9     double x,y;
     10     Point(double x=0,double y=0):x(x),y(y){}
     11 }po[100005];
     12 typedef Point Vector;
     13 
     14 vector<Point> vp;
     15 
     16 int dcmp(double x)
     17 {
     18     if(abs(x)<eps) return 0;
     19     return x>0?1:-1;
     20 }
     21 
     22 bool operator==(const Point &a,const Point &b){
     23     return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
     24 }
     25 
     26 Vector operator-(Point a,Point b){
     27     return Vector(a.x-b.x,a.y-b.y);
     28 }
     29 
     30 Vector operator+(Vector a,Vector b){
     31     return Vector(a.x+b.x,a.y+b.y);
     32 }
     33 
     34 Vector operator*(Vector a,double b){
     35     return Vector(a.x*b,a.y*b);
     36 }
     37 
     38 Vector operator/(Vector a,double b){
     39     return Vector(a.x/b,a.y/b);
     40 }
     41 
     42 bool operator<(const Point &a,const Point &b){
     43     return a.x<b.x||(a.x==b.x&&a.y<b.y);
     44 }
     45 
     46 double Dot(Vector a,Vector b){
     47     return a.x*b.x + a.y*b.y;
     48 }
     49 
     50 double Cross(Vector a,Vector b){
     51     return a.x*b.y - a.y*b.x;
     52 }
     53 
     54 double Length(Vector a){
     55     return sqrt(Dot(a,a));
     56 }
     57 
     58 double Angle(Vector a,Vector b){
     59     return acos(Dot(a,b) / Length(a) / Length(b));
     60 }
     61 
     62 Point getLineIntersection(Point a,Vector va , Point b , Vector vb){
     63     Vector c = a-b;
     64     double t = Cross(vb,c) / Cross(va,vb);
     65     return a+va*t;
     66 }
     67 
     68 bool onSegment(Point a,Point st,Point la){
     69     return dcmp(Cross(st-a,la-a)) == 0 && dcmp(Dot(st-a,la-a)) < 0;
     70 }
     71 
     72 bool onIntersection(Point a , Point b , Point c , Point d){
     73     double t1 = dcmp(Cross(b-a , c-a)) , t2 = dcmp(Cross(b-a , d-a));
     74     double t3 = dcmp(Cross(d-c , b-c)) , t4 = dcmp(Cross(d-c , a-c));
     75     return t1*t2 < 0 && t3*t4<0;
     76 }
     77 
     78 int main()
     79 {
     80   // freopen("test.in","rb",stdin);
     81     int kase = 0;
     82     int n,x,y,e,c;
     83     while(~scanf("%d",&n)){
     84         if(n==0) break;
     85 
     86         vp.clear();
     87         for(int i=0;i<n;i++){
     88             scanf("%d%d",&x,&y);
     89             po[i].x = x,po[i].y = y;
     90             vp.push_back(po[i]);
     91         }
     92         n--;
     93         e=n;
     94         for(int i=0;i<n;i++){
     95             for(int j=i+1;j<n;j++){
     96                 //if(i==j) continue;
     97                 if(onIntersection(po[i],po[i+1],po[j],po[j+1])){
     98                     vp.push_back(getLineIntersection(po[i],po[i+1]-po[i],po[j],po[j+1]-po[j]));
     99                 }
    100             }
    101         }
    102         sort(vp.begin(),vp.end());
    103         c=unique(vp.begin(),vp.end()) - vp.begin();
    104         for(int i=0;i<c;i++){
    105             for(int j=0;j<n;j++){
    106                 if(onSegment(vp[i],po[j],po[j+1]))
    107                     e++;
    108             }
    109         }
    110         printf("Case %d: There are %d pieces.
    ",++kase,e-c+2);
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    [原]Linux 命令行浏览器
    Linux 命令行浏览器
    [原]Linux 命令行 发送邮件
    Linux 命令行 发送邮件
    [原]Linux 修改时区
    Linux 修改时区
    [原]Ubuntu 下安装Mongodb
    离线解密RDP凭证密码
    [Win]权限维持
    Nginx反向代理
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4015070.html
Copyright © 2011-2022 走看看