ZOJ 1460 欧拉定理

题意:

有一块1000*1000的蛋糕,切几刀以后问切成了几块。
题中说:"The intersections of the cut line and the cake edge are two"即每一刀和蛋糕的边缘交点为两个。描述每一刀的时候就是用这两个交点描述的。(在台湾的一个BBS上看到有人说有的时候交点并不是两个,那么应该切的正好是蛋糕边缘)。

 

题解:

欧拉定理。V-E+R=2。

又写wa了,果断超起题解。。我太无节操了。。。

 

View Code
  1 #include <iostream>

  2 #include <cstdio>

  3 #include <cstring>

  4 #include <algorithm>

  5 #include <cstdlib>

  6 #include <cmath>

  7 

  8 #define N 2222

  9 #define EPS 1e-7

 10 

 11 using namespace std;

 12 

 13 struct PO

 14 {

 15     double x,y;

 16 }p[N];

 17 

 18 struct LI

 19 {

 20     PO a,b;

 21     void in(double x1,double y1,double x2,double y2)

 22     {

 23         a.x=x1; a.y=y1; b.x=x2; b.y=y2;

 24     }

 25     void prt()

 26     {

 27         printf("%lf   %lf    %lf     %lf\n",a.x,a.y,b.x,b.y);

 28     }

 29 }li[N],tl;

 30 

 31 int n,ee,nn,cnt,tn;

 32 

 33 inline PO operator -(PO a,PO b)

 34 {

 35     PO c;

 36     c.x=a.x-b.x; c.y=a.y-b.y;

 37     return c;

 38 }

 39 

 40 inline int dc(double x)

 41 {

 42     if(x>EPS) return 1;

 43     else if(x<-EPS) return -1;

 44     return 0;

 45 }

 46 

 47 inline double cross(PO &a,PO &b,PO &c)

 48 {

 49     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);

 50 }

 51 

 52 inline bool same(LI &a,LI &b)//a,b共线 

 53 {

 54     if(dc(cross(a.a,a.b,b.a))==0&&dc(cross(a.a,a.b,b.b))==0) return true;

 55     else return false;

 56 }

 57 

 58 inline bool thesame(LI a)

 59 {

 60     for(int i=1;i<=n;i++)

 61         if(same(a,li[i])) return true;

 62     return false;

 63 }

 64 

 65 inline bool onseg(PO &a,PO &b,PO &c)//c在ab线段上 

 66 {

 67     double maxx=max(a.x,b.x);

 68     double maxy=max(a.y,b.y);

 69     double minx=min(a.x,b.x);

 70     double miny=min(a.y,b.y);

 71     if(dc(cross(a,b,c))==0&&dc(c.x-minx)>=0&&dc(c.x-maxx)<=0&&dc(c.y-miny)>=0&&dc(c.y-maxy)<=0)

 72         return true;

 73     return false;

 74 }

 75 

 76 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)//直线交点 

 77 {

 78     PO ans,tp=b-a;

 79     double k1=cross(a,d,c);

 80     double k2=cross(b,c,d);

 81     ans.x=a.x+tp.x*k1/(k1+k2);

 82     ans.y=a.y+tp.y*k1/(k1+k2);

 83     return ans;

 84 }

 85 

 86 inline bool segcross(LI &a,LI &b)//判断线段相交(不规范) 

 87 {

 88     int d1,d2,d3,d4;

 89     d1=dc(cross(b.a,b.b,a.a));

 90     d2=dc(cross(b.a,b.b,a.b));

 91     d3=dc(cross(a.a,a.b,b.a));

 92     d4=dc(cross(a.a,a.b,b.b));

 93     if(d1*d2<0&&d3*d4<0) return true;

 94     if(d1==0&&onseg(b.a,b.b,a.a)) return true;

 95     if(d2==0&&onseg(b.a,b.b,a.b)) return true;

 96     if(d3==0&&onseg(a.a,a.b,b.a)) return true;

 97     if(d4==0&&onseg(a.a,a.b,b.b)) return true;

 98     return false;

 99 }

100 

101 inline void check(PO x)

102 {

103     for(int i=1;i<=n;i++)

104         if(onseg(li[i].a,li[i].b,x)) ee++;

105 }

106 

107 inline bool cmp(const PO &a,const PO &b)

108 {

109     if(dc(a.x-b.x)==0) return dc(a.y-b.y)<0;

110     return dc(a.x-b.x)<0;

111 }

112 

113 inline bool cmp1(const PO &a,const PO &b)

114 {

115     return dc(a.x-b.x)==0&&dc(a.y-b.y)==0;

116 }

117 

118 inline void go()

119 {

120     cnt=ee=0;

121     for(int i=1;i<=n;i++)

122         for(int j=i+1;j<=n;j++)

123             if(segcross(li[i],li[j]))

124             {

125                 PO jd=getpoint(li[i].a,li[i].b,li[j].a,li[j].b);

126                 if(dc(jd.x)>=0&&dc(jd.x-1000.0)<=0&&dc(jd.y)>=0&&dc(jd.y-1000.0)<=0)

127                     p[++cnt]=jd;

128             }

129     sort(p+1,p+1+cnt,cmp);

130     int nn=unique(p+1,p+1+cnt,cmp1)-p-1;

131     for(int i=1;i<=nn;i++) check(p[i]);

132     //printf("%d    %d     %d",ee,nn,n);

133     printf("%d\n",((ee-n)-nn+2)-1);

134 }

135 

136 inline void read()

137 {

138     li[1].in(0,0,1000,0);

139     li[2].in(0,0,0,1000);

140     li[3].in(0,1000,1000,1000);

141     li[4].in(1000,0,1000,1000);

142     n=4;

143     while(tn--)

144     {

145         scanf("%lf%lf%lf%lf",&tl.a.x,&tl.a.y,&tl.b.x,&tl.b.y);

146         if(!thesame(tl)) li[++n]=tl;

147     }

148     //for(int i=1;i<=n;i++) li[i].prt();

149 }

150 

151 int main()

152 {

153     while(scanf("%d",&tn),tn) read(),go();

154     return 0;

155 }

 

 

你可能感兴趣的:(ZOJ)