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 }
没有人能阻止我前进的步伐,除了我自己!