DIY群赛 1004

#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> using namespace std; __int64 f_min(__int64 x,__int64 y){ return x>y?y:x; } __int64 f_max(__int64 x,__int64 y){ return x<y?y:x; } class point{ private: __int64 px,py; public: void set(){ scanf("%I64d%I64d",&px,&py); } void set(__int64 xx,__int64 xy){ px=xx;py=xy; } __int64 x(){return px;} __int64 y(){return py;} }; __int64 get_gcd(__int64 x,__int64 y){ __int64 t; while(x%y){ t=x%y; x=y; y=t; } return y; } class frac{ private: __int64 fz,fm; bool sym; public: bool small(__int64 x){ __int64 temp; if(sym)temp=fz; else temp=-fz; return temp<=fm*x; } bool big(__int64 x){ __int64 temp; if(sym)temp=fz; else temp=-fz; return temp>=fm*x; } void div(__int64 x,__int64 y){ sym=1; if(x<0){ sym^=1;x=-x; } if(y<0){ sym^=1;y=-y; } __int64 gcd=get_gcd(x,y); fz=x/gcd; fm=y/gcd; } void change(__int64 m,__int64 x,__int64 y,__int64 z){ __int64 gcd; if(sym)m=-m; fz+=fm*m; if(fz<0){ sym^=1; fz=-fz; } gcd=get_gcd(fz,fm); fz/=gcd;fm/=gcd; if(x<0){ sym^=1;x=-x; } if(y<0){ sym^=1;y=-y; } gcd=get_gcd(x,y); fz*=x/gcd;fm*=y/gcd; if(!sym)z=-z; fz+=fm*z; if(fz<0){ sym^=1; fz=-fz; } gcd=get_gcd(fz,fm); fz/=gcd;fm/=gcd; } void disp(){ if(!sym&&fz)printf("-"); printf("%I64d",fz); if(fm!=1&&fz)printf("/%I64d",fm); } }; class line{ private: point s,e; public: void set(){ point temp; s.set();e.set(); if(s.x()>e.x()){ temp=s;s=e;e=temp; } } bool ispoint(){ return (s.x()==e.x()&&s.y()==e.y()); } bool friend check_point(line x,line y){ if(x.ispoint()){ if(y.ispoint()){ if(x.s.x()==y.s.x()&&x.s.y()==y.s.y()){ printf("1/n%I64d %I64d/n",x.s.x(),x.s.y()); }else{ printf("0/n"); } return 1; } if((y.e.y()-y.s.y())*(y.e.x()-x.s.x())==(y.e.x()-y.s.x())*(y.e.y()-x.s.y())){ if(x.s.x()<=y.e.x()&&x.s.x()>=y.s.x()&&x.s.y()>=f_min(y.s.y(),y.e.y())&&x.s.y()<=f_max(y.s.y(),y.e.y())){ //就是这里!!当一条线段是点,另一条线段垂直于x轴时,原来的代码只考虑点的x坐标是否在线段两点间,没考虑y坐标,就会出错=。= //怎么办?感觉这反映出了我的思维逻辑的不严密性,思考问题不够周到,以后做题目也会各种BUG,各种没考虑,各种找不出错误 //这怎么改?!!怎么办怎么办?!!!! //我思考来思考去,觉得我应该更勤奋!!=。=要写注释啦=。= //这里上上那个if写上判断是否三点一线 //上个if写上判断点是否在线段内,这样跟着程序走一遍时效率会高很多 //这样我也不会懒得走了,这样我就不会盲目的找BUG了 //然后这种线段的题目肯定会考虑与坐标轴平行垂直的特殊情况 //然后跟着程序走一遍的时候,一看注释再一想就想到了嘛!!!!! //勤能补挫,总结完毕 printf("1/n%I64d %I64d/n",x.s.x(),x.s.y()); return 1; } } printf("0/n"); return 1; } if(y.ispoint()){ if((x.e.y()-x.s.y())*(x.e.x()-y.s.x())==(x.e.x()-x.s.x())*(x.e.y()-y.s.y())){ if(y.s.x()<=x.e.x()&&y.s.x()>=x.s.x()&&y.s.y()>=f_min(x.s.y(),x.e.y())&&y.s.y()<=f_max(x.s.y(),x.e.y())){ printf("1/n%I64d %I64d/n",y.s.x(),y.s.y()); return 1; } } printf("0/n"); return 1; } return 0; } void friend cross_point(line x,line y){ //printf("^%I64d/n",y.s.y()); __int64 key1=(x.e.x()-x.s.x())*(y.e.y()-y.s.y()); __int64 key2=(y.e.x()-y.s.x())*(x.e.y()-x.s.y()); __int64 key=key1-key2; if(key==0){ if((y.e.y()-y.s.y())*(y.e.x()-x.s.x())==(y.e.y()-x.s.y())*(y.e.x()-y.s.x())){ line temp; if(x.s.x()==x.e.x()){ if(x.s.y()==y.s.y()){ printf("INF/n"); return ; } if(x.s.y()>y.s.y()){ temp=x;x=y;y=temp; } if(x.e.y()<y.s.y()){ printf("0/n"); return; } if(x.e.y()==y.s.y()){ printf("1/n%I64d %I64d/n",x.s.x(),x.e.y()); return; } if(x.e.y()>y.s.y()){ printf("INF/n"); return ; } }else{ if(x.s.x()>y.s.x()){ temp=x;x=y;y=temp; } if(x.e.x()<y.s.x()){ printf("0/n"); return; } if(x.e.x()==y.s.x()){ printf("1/n%I64d %I64d/n",x.e.x(),x.e.y()); return; } if(x.e.x()>y.s.x()){ printf("INF/n"); return ; } } } printf("0/n"); return; } //printf("%I64d %I64d %I64d/n",key1,key2,key); __int64 tcrsx; frac crsx,crsy; tcrsx=__int64(x.s.y()-y.s.y())*(x.e.x()-x.s.x())*(y.e.x()-y.s.x()); //printf("%I64d/n",tcrsx); tcrsx-=(__int64)key2*x.s.x()-key1*y.s.x(); //printf("%I64d/n",tcrsx); crsx.div(tcrsx,key); crsy=crsx; //printf("*%I64d %I64d %I64d %I64d/n",y.s.x(),y.e.y()-y.s.y(),y.e.x()-y.s.x(),y.s.y()); if(y.e.x()==y.s.x())crsy.change(x.s.x(),x.e.y()-x.s.y(),x.e.x()-x.s.x(),x.s.y()); else crsy.change(y.s.x(),y.e.y()-y.s.y(),y.e.x()-y.s.x(),y.s.y());//*a/b+c //printf("%.2lf/n",insx); if(crsx.small(f_max(x.e.x(),x.s.x()))&&crsx.big(f_min(x.e.x(),x.s.x()))){ if(crsx.small(f_max(y.e.x(),y.s.x()))&&crsx.big(f_min(y.e.x(),y.s.x()))){ printf("1/n"); crsx.disp(); printf(" "); crsy.disp(); printf("/n"); return; } } printf("0/n"); return; } }; line a,b; int main(){ int t; scanf("%d",&t); while(t--){ a.set();b.set(); if(check_point(a,b))continue; cross_point(a,b); } return 0; } /* 234 -1 0 0 2 2 2 2 4 */

你可能感兴趣的:(Class,div)