• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
HaibaraAi
博客园    首页    新随笔    联系   管理    订阅  订阅

Warm up 14 [C] Any Way You Slice It

Any Way You Slice It
Time Limit: 3000ms, Special Time Limit:7500ms, Memory Limit:65536KB
Total submit users: 16, Accepted users: 13
Problem 12760 : No special judgement
Problem description

The Association for Cutting Machinery (ACM) has just announced a new portable laser capable of slicing through six-inch sheet metal like a hot knife through Jello (or butter, if you're a traditionalist). The laser is mounted on a small motorized vehicle which is programmed to drive over the surface being cut. The vehicle has two operations: it can move forward in a straight line, cutting the surface beneath it as it goes, or it can pivot in place to face a different direction.

Of course, trouble can arise if the laser cuts a hole in the surface, as the surface inside the hole will drop out, and the vehicle will fall in the hole. Your task is to take a set of instructions for the vehicle and decide whether they will result in cutting a hole—that is, if the path that it is cutting ever intersects itself. We will assume that we have an infinite surface, and that the laser makes a cut of zero width.

We assume that the starting location of the laser is (0, 0) and oriented to face in the positive Y direction. Sequences of instructions will always alternate between turn instructions and move instructions. All instructions are relative—e.g., turn a certain number of counterclockwise degrees relative to your current position. For example, suppose we gave the vehicle the following sequence of instructions:

TURN  -90
MOVE   10
TURN   90
MOVE    5
TURN  135
MOVE   10
TURN  -90
MOVE    5

The vehicle will take the following actions:

  1. Turn -90°. The laser is still at (0, 0), but now the vehicle is facing in the positive X direction.
  2. Move forward 10. This moves the laser to location (10, 0).
  3. Turn 90°. The laser is still at (10, 0), but now the vehicle is facing in the positive Y direction.
  4. Move forward 5. This moves the laser to location (10, 5). (See Figure 1)
  5. Turn 135°. Now the vehicle is facing diagonally in the negative XY direction.
  6. Move forward 10. If this instruction were completed, it would move the laser to approximately (2.93, -2.07). However, along the way the laser will intersect one of the previous cuts it made, making a hole and interfering with the mobility of the vehicle. (See Figure 2) Thus, this instruction (and all following instructions) cannot be completed.
Figure 1: after 2 turn/move instructions Figure 2: after 3 turn/move instructions



Input
The input will be a series of at most 20 data sets. Each data set begins with a line containing an integer N representing the number of turn/move combinations that will be executed (1 ≤ N ≤ 100). A value of zero for N indicates the end of the input.

 

The next N lines contain the instructions. Each instruction contains two integers T and M, where T is the number of degrees to turn (-179 ≤ T ≤ 179) and M is the distance to move after that turn (1 ≤ M ≤ 100).

Note that, although T and M will be integers, you should not assume the position of the laser will always be integer coordinates; in fact, they will typically not be integral. We have taken care to choose data sets for which lines that intersect do so sufficiently away from an endpoint, and that lines that do not intersect remain sufficiently separated from each other.

Output
For each data set you should output the number of the first move instruction that will create a hole (e.g., output 3 if the third move creates the hole). Note that once you have detected a hole, the remaining instructions are irrelevant and may be ignored (but must still be read from the input).

 

If the entire set of instructions can be carried out without creating a hole, then print the word SAFE.

Sample Input
4
-90 10
90 5
135 10
-90 5
4
-90 10
90 5
135 5
-90 10
6
60 10
60 10
60 10
60 10
60 10
80 20
0
Sample Output
3
SAFE
6
Problem Source
mcpc 2012

Submit   Discuss   Judge Status  Problems  Ranklist 
 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include <map>
 3 #include <queue>
 4 #include <vector>
 5 #include <string>
 6 #include <cmath>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <cstdlib>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define maxn 100005
14 #define ll long long
15 #define INF 0x7fffffff
16 #define eps 1e-8 
17 #define zero(x) (((x)>0?(x):-(x))<eps) 
18 struct point{double x,y;};
19 struct line{point a,b;};  
20 double xmult(point p1,point p2,point p0){  return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } 
21 double xmult(double x1,double y1,double x2,double y2,double x0,double y0){  return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0); }
22 int dots_inline(point p1, point p2, point p3){ return zero(xmult(p1, p2, p3)); } 
23 int dots_inline(double x1, double y1, double x2, double y2, double x3, double y3){ return zero(xmult(x1, y1, x2, y2, x3, y3)); }
24 int dot_online_in(point p,line l){  return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps; } 
25 int dot_online_in(point p,point l1,point l2){  return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps; } 
26 int dot_online_in(double x,double y,double x1,double y1,double x2,double y2){ return zero(xmult(x, y, x1, y1, x2, y2)) && (x1 - x)*(x2 - x)<eps && (y1 - y)*(y2 - y)<eps; }
27 int same_side(point p1, point p2, line l){ return xmult(l.a, p1, l.b)*xmult(l.a, p2, l.b)>eps; } 
28 int same_side(point p1, point p2, point l1, point l2){ return xmult(l1, p1, l2)*xmult(l1, p2, l2)>eps; }
29 int intersect_in(line u, line v){
30     if (!dots_inline(u.a, u.b, v.a) || !dots_inline(u.a, u.b, v.b))   return !same_side(u.a, u.b, v) && !same_side(v.a, v.b, u); 
31     return dot_online_in(u.a, v) || dot_online_in(u.b, v) || dot_online_in(v.a, u) || dot_online_in(v.b, u); 
32 }
33 int intersect_in(point u1, point u2, point v1, point v2){ 
34     if (!dots_inline(u1, u2, v1) || !dots_inline(u1, u2, v2)) 
35         return !same_side(u1, u2, v1, v2) && !same_side(v1, v2, u1, u2);  
36     return dot_online_in(u1, v1, v2) || dot_online_in(u2, v1, v2) || dot_online_in(v1, u1, u2) || dot_online_in(v2, u1, u2); 
37 }
38 line lx[maxn];
39 int n, m;
40 int main(){
41     int cas = 1;
42     while (scanf("%d", &n)&&n){
43         memset(lx, 0, sizeof lx);
44         int k = 0;
45         double t = 0;
46         lx[0].a.x = lx[0].a.y = 0;
47         for (int i = 0; i < n; i++){
48             double a, b;
49             scanf("%lf%lf", &a, &b);
50             t += a;
51             lx[i].b.x = lx[i].a.x - b * sin(t/180*3.1415926);
52             lx[i].b.y = lx[i].a.y + b * cos(t / 180 * 3.1415926);
53             lx[i + 1].a = lx[i].b;
54             if (i <=1||k)continue;
55             for (int j = 0; j < i-1; j++){
56                 if (intersect_in(lx[i], lx[j]) && k == 0){k = i; break;}
57             }
58         }
59         if (k == 0)printf("SAFE\n");
60         else printf("%d\n", k + 1);
61     }
62     return 0;
63 }
View Code
posted @ 2013-10-28 15:07  HaibaraAi  阅读(116)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3