Right turn【模拟+标记】

Right turn

题目链接(点击)

frog is trapped in a maze. The maze is infinitely large and divided into grids. It also consists of nn obstacles, where the ii-th obstacle lies in grid (xi,yi)(xi,yi).

frog is initially in grid (0,0)(0,0), heading grid (1,0)(1,0). She moves according to The Law of Right Turn: she keeps moving forward, and turns right encountering a obstacle.

The maze is so large that frog has no chance to escape. Help her find out the number of turns she will make.

Input

The input consists of multiple tests. For each test:

The first line contains 11 integer nn (0≤n≤1030≤n≤103). Each of the following nn lines contains 22 integers xi,yixi,yi. (|xi|,|yi|≤109,(xi,yi)≠(0,0)|xi|,|yi|≤109,(xi,yi)≠(0,0), all (xi,yi)(xi,yi) are distinct)

Output

For each test, write 11 integer which denotes the number of turns, or ``-1'' if she makes infinite turns.

Sample Input

    2
    1 0
    0 -1
    1
    0 1
    4
    1 0
    0 1
    0 -1
    -1 0

Sample Output

    2
    0
    -1

题意:

在无边界的坐标中 给出n个石头所在坐标 开始在坐标原点 头朝向x轴正方向 每次可以走无数步 但要求所走的是一条直线 如果前面遇到石头 则右转 最后输出转向次数 如果永远出不去 则输出 -1

思路:

很好的一道模拟题 记录 头的朝向 和 每个石头所在位置

从原点开始 判断在这一行有没有石头并且y的坐标相同 如果有则所在位置移动到该石头的前一个点 转向次数+1 然后把头转向

如果没有 直接输出转向次数

如果一直在坐标系中转圈 输出-1 所以需要标记

做题的时候遇到两个问题:

错误一、我用了1维数组标记走过的石头 如果下次再遇到 就输出-1

因为:有可能出现下面这种情况 并不需要输出-1 

红点走了两次而不需要输出-1

解决方法:

不仅要标记走过的石头还要标记从哪个方向过来这个石头的 如果下次还是这个方向过来的肯定要输出-1了

错误二、  对输入的坐标先进行了sort排序 

因为cmp函数中只是进行了将x从小到大排序  而y并非也是从小到大排序 所以若要找到在其前方(因为是往头所指的方向走 所以是前面)第一个符合条件的坐标 要分别按x或y排序才可以(我没试 但估计会T)

也可以每次都把所有坐标都跑一边 找到在其前方的第一个符合条件的点(具体可以看代码中judge函数)

AC代码:

#include<stdio.h>
#include<string.h>
const int INF=1e9+5;
const int MAX=1e3;
int n;
int flag[MAX+5][5],head;
struct node{
    int x;
    int y;
}edge[MAX+5];
int judge(int x,int y)
{
    if(head==1){
        int minn=INF,minn1;
        for(int i=0;i<n;i++){
            if(edge[i].x<minn&&edge[i].x>x&&edge[i].y==y){
                minn=edge[i].x;
                minn1=i;
            }
        }
        if(minn==INF){
            return -2;
        }
        else if(flag[minn1][1]==1){
            return -1;
        }
        else{
            flag[minn1][1]=1;
            return minn1;
        }
    }
    else if(head==2){
        int minn=-INF,minn1;
        for(int i=0;i<n;i++){
            if(edge[i].y>minn&&edge[i].y<y&&edge[i].x==x){
                minn=edge[i].y;
                minn1=i;
            }
        }
        if(minn==-INF){
            return -2;
        }
        else if(flag[minn1][2]==1){
            return -1;
        }
        else{
            flag[minn1][2]=1;
            return minn1;
        }
    }
    else if(head==3){
        int minn=-INF,minn1;
        for(int i=0;i<n;i++){
            if(edge[i].x>minn&&edge[i].x<x&&edge[i].y==y){
                minn=edge[i].x;
                minn1=i;
            }
        }
        if(minn==-INF){
            return -2;
        }
        else if(flag[minn1][3]==1){
            return -1;
        }
        else{
            flag[minn1][3]=1;
            return minn1;
        }
    }
    else{
        int minn=INF,minn1;
        for(int i=0;i<n;i++){
            if(edge[i].y<minn&&edge[i].y>y&&edge[i].x==x){
                minn=edge[i].y;
                minn1=i;
            }
        }
        if(minn==INF){
            return -2;
        }
        else if(flag[minn1][4]==1){
            return -1;
        }
        else{
            flag[minn1][4]=1;
            return minn1;
        }
    }
}
int main()
{
    while(~scanf("%d",&n)){
        memset(flag,0,sizeof(flag));
        for(int i=0;i<n;i++){
            scanf("%d%d",&edge[i].x,&edge[i].y);
        }
        int x=0,y=0,ans=0;head=1;
        while(1){
            //printf("%d %d\n",x,y);
            int num=judge(x,y);
            //printf("%d\n",num);
            if(num==-1){
                printf("-1\n");
                break;
            }
            else if(num==-2){
                printf("%d\n",ans);
                break;
            }
            else{
                ans++;
                if(head==1){
                    head=2;
                    x=edge[num].x-1,y=edge[num].y;
                }
                else if(head==2){
                    head=3;
                    x=edge[num].x,y=edge[num].y+1;
                }
                else if(head==3){
                    head=4;
                    x=edge[num].x+1,y=edge[num].y;
                }
                else{
                    head=1;
                    x=edge[num].x,y=edge[num].y-1;
                }
            }
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值