If you look for the most distant point in the X-axis, then just look if the Y-axis in the next coordinate goes up or down. The only bug I think it has is if the most distant point is the latest, but in that case you use 1 point before adn do the same task. It's not a good idea. Please try (0,0),(1,0),(2,2),(0,1). It's ccw,but in your mind is cw. I got WA on test 7 all the time...... I submited many times . But still WA. Can anyone help me ? This is my code : ------------------------------------------------------------ {$A+,B+,D+,E+,F+,G+,I+,L+,N+,O+,P+,Q+,R+,S+,T+,V+,X+} {$M 16384,0,655360} type node = record x , y : Array [0..201] Of LongInt ; tx , ty , lx , ly : LongInt ; end; var up , down , right1 , right2 , right3 , now : node ; h : Array [1..5] Of LongInt ; i , n : LongInt ; t : Boolean ; procedure init ; var c : Char ; s : Set Of Char ; begin s := ['0'..'9','-'] ; With now do begin repeat read ( c ) ; until c in s ; if c = '-' then begin tx := 2 ; read ( c ) ; end else tx := 1 ; lx := 0 ; repeat Inc ( lx ) ; x[lx] := ord ( c ) - 48 ; read ( c ) ; until c = ' ' ; repeat read ( c ) ; until c in s ; if c = '-' then begin tx := 2 ; read ( c ) ; end else ty := 1 ; ly := 0 ; repeat Inc ( ly ) ; y[ly] := ord ( c ) - 48 ; read ( c ) ; until Not ( c in s ) ; end; end; procedure first ; begin up.ty := 2 ; up.ly := MaxInt ; down.ty := 1 ; down.ly := MaxInt ; right1.tx := 2 ; right1.lx := MaxInt ; right2.tx := 2 ; right2.lx := MaxInt ; right3.tx := 2 ; right3.lx := MaxInt ; end; Function check_y ( h : node ) : Boolean ;{true:big} var i : LongInt ; judge : Boolean ; begin if h.ty <> now.ty then begin if h.ty = 1 then check_y := false else check_y := true ; exit end; if h.ty = 1 then judge := true else judge := false ; if h.ly <> now.ly then begin if h.ly < now.ly then check_y := judge else check_y := not judge ; exit ; end; for i := 1 to now.ly do if h.y[i] <> now.y[i] then begin if h.y[i] < now.y[i] then check_y := judge else check_y := not judge ; exit ; end; check_y := false ; end; Function check_x ( h , now : node ) : Boolean ;{true:small} var i : LongInt ; judge : Boolean ; begin if h.tx <> now.tx then begin if h.tx = 1 then check_x := false else check_x := true ; exit ; end; if h.tx = 1 then judge := true else judge := false ; if h.lx <> now.lx then begin if h.lx < now.lx then check_x := judge else check_x := not judge ; exit ; end; for i := 1 to now.lx do if h.x[i] <> now.x[i] then begin if h.x[i] < now.x[i] then check_x := judge else check_x := not judge ; exit ; end; check_x := false ; end; procedure yes ; begin writeln ( 'cw' ) ; end; procedure no ; begin writeln ( 'ccw' ) ; end; begin first ; readln ( n ) ; for i := 1 to n do begin init ; t := false ; if check_y ( up ) then begin h[1] := i ; up := now ; t := true ; end; if Not check_y ( down ) then begin h[2] := i ; down := now ; t := true ; end; if check_x ( right1 , now ) then begin h[5] := h[4] ; right3 := right2 ; h[4] := h[3] ; right2 := right1 ; h[3] := i ; right1 := now ; end else if check_x ( right2 , now ) then begin h[5] := h[4] ; right3 := right2 ; h[4] := i ; right2 := now ; end else if check_x ( right3 , now ) then begin h[5] := i ; right3 := now ; end; end; if ( h[3] = h[2] ) or ( h[3] = h[1] ) then h[3] := h[4] ; if ( h[3] = h[2] ) or ( h[3] = h[1] ) then begin h[3] := h[5] ; if h[1] < h[3] then begin if ( h[2] > h[1] ) and ( h[2] < h[3] ) then yes else no ; end else begin if ( h[2] > h[3] ) and ( h[2] < h[1] ) then no else yes ; end; halt ; end; if h[1] < h[3] then begin if ( h[2] > h[1] ) and ( h[2] < h[3] ) then no else yes ; end else begin if ( h[2] < h[1] ) and ( h[2] > h[3] ) then yes else no ; end; end. Edited by author 14.06.2004 09:08 I summarise all corners of this polygon and see: if a>0(360)->ccw; else (a=-360)->cw; Why is it wrong? This is my program: #include<iostream.h> #include<math.h> double len(double x1,double y1,double x2,double y2) {return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} double gon(double x1,double y1,double x2,double y2,double x3,double y3) {return asin(((x2-x1)*(y3-y2)-(x3-x2)*(y2-y1))/(len(x1,y1,x2,y2)*len (x2,y2,x3,y3)));} int main() { double a=0,x0,y0,x1,y1,xl,yl,xr,yr,xn,yn; long n,i; cin >> n; cin >> x0 >> y0 >> x1 >> y1; xl=x0; yl=y0; xr=x1; yr=y1; for (i=3; i<=n; i++) { cin >> xn >> yn; a+=gon(xl,yl,xr,yr,xn,yn); xl=xr; yl=yr; xr=xn; yr=yn; } a+=gon(xl,yl,xr,yr,x0,y0); a+=gon(xr,yr,x0,y0,x1,y1); if (a<0) cout << "cw"; else cout << "ccw"; return 0; } My program uses the following method: I choose the upper, lower and rightmost points and then sort them in the order they were visited. Suppose their coordinates are (x1,y1), (x2,y2), (x3,y3), where 1 was the first visited, 2 - second and 3 - third. Then I put them in a martix x1 y1 1 x2 y2 1 x3 y3 1 and calculate D=x1*y2*1-x3*y2*1. If D>0, the 3 points are oriented clockwise. When D<0, then orientation is counterclockwise. But what happens when D=0? And why is my method wrong for the sample input? Pls help me! Vallery777@yahoo.com Is it posible to solve it using only the first 2 coordinates? I already found a solution but it uses 3 coordinates and I have to read all coordinates first. For each line segment (x1; y1) (x2; y2) I calculate cross product of 2 vectors: (0; 0) (x1; y1) and (0; 0) (x2; y2) Summing all cross products gives double square of polygon but with one exception: it is positive if vertices are situated ccw and negative otherwise (cw). Just look for the upper, the lower and the most to the right points. Then label then acording on how you found them (e.g.: if you find the lower first then you give it a lower number than the upper point, I used "i" for this). Then you just have to check the sequence. If you have any problem understanding this, I can post my solution. PS: This algorithm has a small bug that you don't have to fix in order to get AC! My program uses the following method: I choose the upper, lower and rightmost points and then sort them in the order they were visited. Suppose their coordinates are (x1,y1), (x2,y2), (x3,y3), where 1 was the first visited, 2 - second and 3 - third. Then I put them in a martix x1 y1 1 x2 y2 1 x3 y3 1 and calculate D=x1*y2*1-x3*y2*1. If D>0, the 3 points are oriented clockwise. When D<0, then orientation is counterclockwise. But what happens when D=0? And why is my method wrong for the sample input? Pls help me! Vallery777@yahoo.com Why is it always ccw? How should I aproach this problem in order to solve it? Thanks! It's cheat. now it can't get ac. You should do with the first and the second coordinat. I can see that with 2 it can be solved for convex polygons, but for not convex? Sorry. actually,it is 3 coords. I add another coordinate myself. > I can see that with 2 it can be solved for convex polygons, but for > not convex? so just find convex hull , and solve it by that method Please give me a hint if got AC. pooya begin writeln('ccw') end. |
|