Algorithm 检查是否存在一个圆

Algorithm 检查是否存在一个圆,algorithm,geometry,computational-geometry,Algorithm,Geometry,Computational Geometry,在谷歌的一次采访中,我被问到了这个问题。 我们得到一个由字母-F,L,R组成的字符串,这是机器人遵循的指令 F-前进一步 左转 右转 字符串长度最多可达2500个字符 字符串自身运行无限次。我们需要知道是否存在一个半径为r的圆(r可以是任何实数),这样机器人就永远不会离开这个圆。 我被困在这一点上。我想使用凸包,但如何检查它的无限次。与代码的解释将不胜感激。请帮忙。提前感谢运行字符串,查看机器人在其末端的位置以及它看起来的方向 如果它回到原点,则取执行期间与原点的最大距离,并与r进行比较 如果未

在谷歌的一次采访中,我被问到了这个问题。 我们得到一个由字母-F,L,R组成的字符串,这是机器人遵循的指令

F-前进一步

左转

右转

字符串长度最多可达2500个字符

字符串自身运行无限次。我们需要知道是否存在一个半径为r的圆(r可以是任何实数),这样机器人就永远不会离开这个圆。
我被困在这一点上。我想使用凸包,但如何检查它的无限次。与代码的解释将不胜感激。请帮忙。提前感谢

运行字符串,查看机器人在其末端的位置以及它看起来的方向

如果它回到原点,则取执行期间与原点的最大距离,并与r进行比较

如果未返回原点,则检查其方向:

如果它的方向与开始时相同,那么它将无限期地远离原点,因此不存在这样的r

如果它的方向与开始时不同,则它将在字符串迭代4或2次后返回原点,具体取决于它是朝向其原始方向的左/右,还是朝向其原始方向的相反方向。现在取两次执行字符串后的最大距离。(简单的案例区分将表明,无论执行2次还是4次,它在执行2次之后都会到达其最大距离。)

  • 每次运行(一次运行执行给定字符串的所有命令一次)都会改变两件事:机器人观察的方向和它的位置(即,每次运行都会将它移动某个向量(该向量的方向取决于运行前的初始方向)并旋转它)
  • 可能的方向数为4。因此,在运行模拟4次后,它看起来与最初的方向相同(每次摩擦将其旋转相同的角度)

  • 这就是为什么连续4次运行只需将其移动一些向量,而不进行任何旋转

  • 因此,我们可以连续运行模拟4次,看看它是否在原点停止。如果有,我们可以找到包含其路径的最小圆。否则,就不存在这样的循环


  • 您将运行1次迭代来计算新位置,比如newx,newy。 然后再计算4次迭代,看看机器人是否回到newx-newy。如果是,则该圆存在,否则不存在

    半径将是机器人在迭代中冒险出来的最大距离

    守则实施-

    //North, South, East, West directions
    #define N 0 
    #define S 1
    #define E 2
    #define W 3
    
    // Function to compute the new pos (x, y, dir) after completing one iteration of the string.
    // It will also update the max radius.
    void findNewPos(char *str, int *origdir, int *origx, int *origy, double *maxrad) {
      int i, len, x, y, dir; 
    
      dir = *origdir;
      x = *origx;
      y = *origy;
    
      len = strlen(str);
      i=0;
    
      //Iterate through each character
      while(i < len) {
        char c = str[i];
    
        switch(c) {
        case 'L': // Turn left
          switch(dir) {
          case N:
             x--;
             dir = W;
             break;
          case S:
             x++;
             dir = E;
             break;
          case E:
             y++;
             dir = N;
             break;
          case W:
             y--;
             dir = S;
             break;
          }
          break;
    
        case 'R': // Turn right
          switch(dir) {
          case N:
             x++;
             dir = E;
             break;
          case S:
             x--;
             dir = W;
             break;
          case E:
             y--;
             dir = S;
             break;
          case W:
             y++;
             dir = N;
             break;
          }
          break;
    
        case 'F': // Go forward
          switch(dir) {
          case N:
             y++;
             dir = N;
             break;
          case S:
             y--;
             dir = S;
             break;
          case E:
             x++;
             dir = E;
             break;
          case W:
             x--;
             dir = W;
             break;
          }
          break;
        }
    
        // Update max radius till now
        double rad = x*x + y*y;
        if(rad > *maxrad)
          *maxrad = rad;
        i++;
      }
    
      *origx = x;
      *origy = y;
      *origdir = dir;
    }
    
    // Function to compute the max radius of movement, if bounded
    double findCircle(char *str) {
      int x=0, y=0, dir=N;
      int refx, refy;
      double radius = 0, maxrad = 0;
    
      // Starting from origin(x=0, y=0), find new pos after single iteration
      findNewPos(str, &dir, &x, &y, &maxrad);
    
      refx = x;
      refy = y;
    
      // Find new positions after 4 more iterations
      findNewPos(str, &dir, &x, &y, &maxrad);
      findNewPos(str, &dir, &x, &y, &maxrad);
      findNewPos(str, &dir, &x, &y, &maxrad);
      findNewPos(str, &dir, &x, &y, &maxrad);
    
      // Are we back to position where we were after 1st iteration?
      if(x == refx && y == refy) {
        printf("Circle exists %f!\n", maxrad);
        radius = sqrt(maxrad);
      }
      else {
        printf("Circle does not exist!\n");
        radius = -1;
      }
    
      return radius;
    }
    
    //北、南、东、西方向
    #定义n0
    #定义s1
    #定义E2
    #定义w3
    //函数在完成字符串的一次迭代后计算新的位置(x,y,dir)。
    //它还将更新最大半径。
    void findNewPos(char*str,int*origdir,int*origx,int*origy,double*maxrad){
    int i,len,x,y,dir;
    dir=*origdir;
    x=*origx;
    y=*origy;
    len=strlen(str);
    i=0;
    //遍历每个字符
    而(我*maxrad)
    *maxrad=rad;
    i++;
    }
    *origx=x;
    *origy=y;
    *origdir=dir;
    }
    //函数计算最大移动半径(如果有界)
    双findCircle(char*str){
    int x=0,y=0,dir=N;
    国际参考文献,参考文献;
    双半径=0,最大半径=0;
    //从原点(x=0,y=0)开始,在单次迭代后找到新的位置
    findNewPos(str、dir、x、y和maxrad);
    refx=x;
    refy=y;
    //再迭代4次后找到新位置
    findNewPos(str、dir、x、y和maxrad);
    findNewPos(str、dir、x、y和maxrad);
    findNewPos(str、dir、x、y和maxrad);
    findNewPos(str、dir、x、y和maxrad);
    //我们是否回到了第一次迭代后的位置?
    如果(x==refx&&y==refy){
    printf(“圆存在%f!\n”,maxrad);
    半径=sqrt(最大弧度);
    }
    否则{
    printf(“圆圈不存在!\n”);
    半径=-1;
    }
    返回半径;
    }
    
    在给定字符串中迭代一次,并记下最终的位移和方向。如果位移为非零,且机器人在单个迭代中的开始和结束方向相同,则机器人不能包含在圆中,否则可以包含在圆中

    图:
    在图中,假设机器人在给定字符串的一次迭代后从A点移动到B点。现在,角度ABC是(90θ),这使得角度ABD等于90度。当所有边都相等,每个角都等于90度时,四边形ABDE就是正方形。这对于θ的任何值(锐角或钝角)都是正确的。如果单次迭代后的结束方向保持不变,则证明类似。对于南方,机器人将在A点和B点之间摆动

    因此,作为问题的解决方案,您可以只检查开始和结束方向是否相同
    string doesCircleExists(string commands) {
        int dir=1; //1 is east; 2 north etc.
        pair<int,int> pos; 
        pos = make_pair(0,0);  //start at origin
        for(int i=0;i<4;i++) {
        for(int i=0;i<commands.size(); i++)
        {
           if(commands[i]=='F')
           {
            if(dir==1) pos.first++;  if(dir==2) pos.second++; 
            if(dir==3) pos.first--; if(dir==0) pos.second--; 
           }
           if(commands[i]=='L') {dir++; dir = dir%4;}
           if(commands[i]=='R') {dir--; dir = dir%4;}
        }
        }
        if(pos.first==0 && pos.second==0 && dir=1) return "YES"; else return "NO";
    
    def encircular(string):
    
        ini_pos = [0,0]
        position = [0,0]
        direction = 'N'
        directions = {'NL':'W','NR':'E','EL':'N','ER':'S','SL':'E','SR':'W','WL':'S','WR':'N'}
        forward = {'N':[0,1],'E':[1,0],'S':[0,-1],'W':[-1,0]}
        for i in range(4):
            for i in string:
                if i == 'F':
                    position = [x+y for x,y in zip(position,forward[direction])]
                else:
                    #print(direction+i)
                    direction = directions[direction+i]
                    #print (direction)
        if ini_pos == position: return 'YES'
        else : return 'NO'
    
    def robot_bot(string):
        face = 0
        pos = [0, 0]
        string = string.upper()
        dirc = {
            0: [1, 0],
            90: [0, 1],
            180: [-1, 0],
            270: [0, -1],
            360: [1, 0],
            -90: [0, -1],
            -180: [-1, 0],
            -270: [0, 1]
        }
        for _ in range(4):
            for ch in string:
                if ch == "R": face -= 90
                elif ch == "L": face += 90
                if ch == "G":
                    pos[0] += dirc[face][0]
                    pos[1] += dirc[face][1]
                if abs(face) == 360:
                    face = 0
        return True if pos == [0, 0] else False
    
    #include <bits/stdc++.h>
    using namespace std;
    struct point
    {
        int x;
        int y;
        int dir;
    };
    int mod4(int a)
    {
        if(a%4 < 0)
            return (a%4 + 4);
        else
            return a%4;
    }
    int main()
    {
        struct point p;
        p.x = 0;
        p.y = 0;
        p.dir = 0;
        string s;cin>>s;
        int j;
        for(int i=0;i<4*s.size();i++)
        {
            j = i%s.size();
            if(s[j] == 'F')
            {
                if(p.dir == 0)//north
                    p.y++;
                if(p.dir == 1)//east
                    p.x++;
                if(p.dir == 2)//south
                    p.y--;
                if(p.dir == 3)//west
                    p.x--;
            }
            if(s[j] == 'L')
            {
                p.dir--;
                p.dir = mod4(p.dir);
            }
            if(s[j] == 'R')
            {
                p.dir++;
                p.dir = mod4(p.dir);
            }
            //cout<<p.x<<" "<<p.y<<" "<<p.dir<<endl;
        }
        if(p.x == 0 && p.y ==0 && p.dir == 0)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;   
    }