「AOJProblem Set from CGL 問0~4」の編集履歴(バックアップ)一覧はこちら

AOJProblem Set from CGL 問0~4」(2014/01/24 (金) 18:35:00) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*Points/Vectors - Projection http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A 正射影を求める問題。 指定されている有効桁数が大きいことだけに注意。 あとはベクトルの知識からすぐに式がたちます。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,lenP1; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; lenP1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double T=(dx1*dx2+dy1*dy2)/(lenP1*lenP1); printf("%.10lf %.10lf\n",x0+dx1*T,y0+dy1*T); } } *Points/Vectors - Reflection http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B 線対称な点を求める問題。 正射影で求めた点の点対称な位置ですので前の問題のコードを流用します。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,lenP1; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; lenP1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double T=(dx1*dx2+dy1*dy2)/(lenP1*lenP1); double tx=x0+T*dx1; double ty=y0+T*dy1; printf("%.10lf %.10lf\n",tx*2-x2,ty*2-y2); } } *Points/Vectors - Counter-Clockwise http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C ベクトルAからみてベクトルBが時計回りか反時計回りかもしくは同一直線状にあるなら細かく判断する問題。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,len1,len2; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; len1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double R=dx1*dy2-dx2*dy1; len2=hypot(dx2,dy2); if(R>0){ printf("COUNTER_CLOCKWISE\n"); }else if(R<0){ printf("CLOCKWISE\n"); }else{ if(dx1*dx2+dy1*dy2<0){ printf("ONLINE_BACK\n"); }else{ if(len1<len2){ printf("ONLINE_FRONT\n"); }else{ printf("ON_SEGMENT\n"); } } } } } *Segments/Lines - Parallel/Orthogonal http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A 内積が0になれば直交。 外積が0になれば平行。 どちらでもなければ0. #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2,x3,y3; double dx1,dx3,dy1,dy3; int q; scanf("%d",&q); while(q--){ scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); scanf("%lf %lf %lf %lf",&x2,&y2,&x3,&y3); dx1=x1-x0; dy1=y1-y0; dx3=x3-x2; dy3=y3-y2; double R1=(dx1*dy3-dx3*dy1); double R2=(dx1*dx3+dy1*dy3); if(R1==0){ printf("2"); }else if(R2==0){ printf("1"); }else{ printf("0"); } printf("\n"); } }
*Points/Vectors - Projection http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A 正射影を求める問題。 指定されている有効桁数が大きいことだけに注意。 あとはベクトルの知識からすぐに式がたちます。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,lenP1; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; lenP1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double T=(dx1*dx2+dy1*dy2)/(lenP1*lenP1); printf("%.10lf %.10lf\n",x0+dx1*T,y0+dy1*T); } } *Points/Vectors - Reflection http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B 線対称な点を求める問題。 正射影で求めた点の点対称な位置ですので前の問題のコードを流用します。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,lenP1; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; lenP1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double T=(dx1*dx2+dy1*dy2)/(lenP1*lenP1); double tx=x0+T*dx1; double ty=y0+T*dy1; printf("%.10lf %.10lf\n",tx*2-x2,ty*2-y2); } } *Points/Vectors - Counter-Clockwise http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C ベクトルAからみてベクトルBが時計回りか反時計回りかもしくは同一直線状にあるなら細かく判断する問題。 #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,len1,len2; scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); dx1=x1-x0; dy1=y1-y0; len1=hypot(dx1,dy1); int q; scanf("%d",&q); while(q--){ scanf("%lf %lf",&x2,&y2); dx2=x2-x0; dy2=y2-y0; double R=dx1*dy2-dx2*dy1; len2=hypot(dx2,dy2); if(R>0){ printf("COUNTER_CLOCKWISE\n"); }else if(R<0){ printf("CLOCKWISE\n"); }else{ if(dx1*dx2+dy1*dy2<0){ printf("ONLINE_BACK\n"); }else{ if(len1<len2){ printf("ONLINE_FRONT\n"); }else{ printf("ON_SEGMENT\n"); } } } } } *Segments/Lines - Parallel/Orthogonal http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A 内積が0になれば直交。 外積が0になれば平行。 どちらでもなければ0. #include<stdio.h> #include<math.h> int main(){ double x0,y0,x1,y1,x2,y2,x3,y3; double dx1,dx3,dy1,dy3; int q; scanf("%d",&q); while(q--){ scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); scanf("%lf %lf %lf %lf",&x2,&y2,&x3,&y3); dx1=x1-x0; dy1=y1-y0; dx3=x3-x2; dy3=y3-y2; double R1=(dx1*dy3-dx3*dy1); double R2=(dx1*dx3+dy1*dy3); if(R1==0){ printf("2"); }else if(R2==0){ printf("1"); }else{ printf("0"); } printf("\n"); } } *Segments/Lines - Intersection http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B 同一直線上に2本の線がある場合の判定で結構困った問題。 採点データを作った人の掌の上で踊ってしまった感じがする。 勉強になりました。 #include<stdio.h> #include<math.h> bool isFlat(double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3){ double dx1,dy1,dx2,dy2,dx3,dy3,R1,R2; dx1=x1-x0; dy1=y1-y0; dx2=x2-x0; dy2=y2-y0; dx3=x3-x0; dy3=y3-y0; R1=dx1*dx2+dy1*dy2; R2=dx1*dx3+dy1*dy3; if(R1<=0&&0<=R2)return true; if(R2<=0&&0<=R1)return true; return false; } bool isCrossHerf(double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3){ double dx1,dy1,dx2,dy2,dx3,dy3; dx1=x1-x0; dy1=y1-y0; dx2=x2-x0; dy2=y2-y0; dx3=x3-x0; dy3=y3-y0; double R1=dx1*dy2-dx2*dy1; double R2=dx1*dy3-dx3*dy1; if(0<R1&&R2<=0)return true; if(0<=R1&&R2<0)return true; if(0<R2&&R1<=0)return true; if(0<=R2&&R1<0)return true; if(R1==0&&R2==0){ bool Hit1=isFlat(x0,y0,x1,y1,x2,y2,x3,y3); bool Hit2=isFlat(x1,y1,x0,y0,x2,y2,x3,y3); bool Hit3=isFlat(x2,y2,x3,y3,x0,y0,x1,y1); bool Hit4=isFlat(x3,y3,x2,y2,x0,y0,x1,y1); return Hit1||Hit2||Hit3||Hit4; } return false; } int main(){ double x0,y0,x1,y1,x2,y2,x3,y3; double dx1,dx3,dy1,dy3; int q; scanf("%d",&q); while(q--){ scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1); scanf("%lf %lf %lf %lf",&x2,&y2,&x3,&y3); bool ok=isCrossHerf(x0,y0,x1,y1,x2,y2,x3,y3)&&isCrossHerf(x2,y2,x3,y3,x0,y0,x1,y1); printf("%d\n",ok?1:0); } }

表示オプション

横に並べて表示:
変化行の前後のみ表示: