scu-4445

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 (0n1030≤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

题意:青蛙在迷宫里面一直向前走,如果遇到障碍,就原地向右转,然后继续向前走。能走出迷宫,输出转向次数。
走不出去,输出-1。


这题前前后后花了我有近5个小时,琢磨出三种方法。
第一种,最笨的,模拟青蛙的一步一步走。
第二种,用for循环找障碍点。
第三种,根据障碍点来确定青蛙的位置。

三种方法的代码我都敲了。
第一种方法不出意料的TLE。
第二种竟然是MLE(第一次遇到这情况,在此纪念下)。
(第二种方法有位学长ac了,感兴趣的同学可以移步http://blog.csdn.net/a1dark/article/details/46583929)
第三种自己动了些脑筋而且一次过了,略微得意,结果前段时间翻博客发现早已经有学长用过这方法了 T T。
(第三种方法学长的博客:http://blog.csdn.net/qq_31759205/article/details/52299244)
我还是太年轻。



讲下第三种方法:
  脑补一个二维坐标轴,青蛙在(0,0)点。
  如果遇到障碍,则青蛙必定会走到障碍的前一个点。因此只需要操作并记录相应的障碍点就行了。
  因为总共就四个方向,所以当一个障碍点被记录四次以上,则是陷入死循环。

附代码:
#include <cstdio>
#include<cstring>
#include<algorithm>
#define Maxx 3333
using namespace std;
struct ak
{
    int x;  //横坐标 
    int y;  //纵坐标 
    int f;  //在nu中用作记录碰到此点的次数 在nux和nuy中记录坐标在nu中的位置 
}nu[Maxx],nux[Maxx],nuy[Maxx];
bool cmpx(ak a,ak b)  //对nux进行x(横坐标)的从小到大排序 
{
    if(a.x<b.x) return 1;
    return 0;
}
bool cmpy(ak a,ak b)  //对nuy进行y(纵坐标)的从小到大排序 
{
    if(a.y<b.y) return 1;
    return 0;
}
int main(void)
{
    int fx,fy,flag=0;      //(fx,fy)为模拟青蛙的坐标  
    int d;                  //d用来记录方向(direction),1,2,3,4分别是坐标的右,下,左,上 
                         //flag用于记录青蛙走迷宫的三种情况  0:遇到障碍 1:死循环  2:走出迷宫 
    int t;                //t(turn)记录青蛙旋转的次数 
    int i,l;                         
    int n;
    while(~scanf("%d",&n))
    {
        fx=0;fy=0;d=1;flag=0;t=0;
        
        for( l=0;l<n;l++)
    {
        scanf("%d %d",&nu[l].x,&nu[l].y);
        nux[l].x=nu[l].x;nux[l].y=nu[l].y;
        nuy[l].x=nu[l].x;nuy[l].y=nu[l].y;
        nux[l].f=l;      nuy[l].f=l;
    }
    sort(nux,nux+l,cmpx);        //对nux进行x(横坐标)的从小到大排序 
    sort(nuy,nuy+l,cmpy);        //对nuy进行y(纵坐标)的从小到大排序 
    while(1)                    //死循环 flag!=0时跳出 
    {    
     if(d==1)                    //四个方向 
     {
         for( i=0;i<l;i++)
         {
             if(nu[nux[i].f].f>4)    //如果在一个点前停止四次以上,则说明陷入死循环 
             {
                 flag=1;
                 break;
             }
             if(nux[i].y==fy&&nux[i].x>fx)    //如果碰到障碍,转向  
             {
                 fx=nux[i].x-1;
                 nu[nux[i].f].f++;
                 t++;
                 d++;
                 break;
             }
         }
         if(i>=l||i<0)
         flag=2;
         
     }
     if(d==2)            //四个方向  同上 
     {
        for( i=l-1;i>=0;i--)
         {
             if(nu[nuy[i].f].f>4)
             {
                 flag=1;
                 break;
             }
             if(nuy[i].x==fx&&nuy[i].y<fy)
             {
                 fy=nuy[i].y+1;
                 nu[nuy[i].f].f++;
                 t++;
                 d++;
                 break;
             }
         }
         if(i>=l||i<0)
         flag=2;
     }
     if(d==3)            //四个方向  同上 
     {
         for( i=l-1;i>=0;i--)
         {
             if(nu[nux[i].f].f>4)
             {
                 flag=1;
                 break;
             }
             if(nux[i].y==fy&&nux[i].x<fx)
             {
                 fx=nux[i].x+1;
                 nu[nux[i].f].f++;
                 t++;
                 d++;
                 break;
             }    
         }
         if(i>=l||i<0)
         flag=2;
     }
     if(d==4)        //四个方向 同上 
     {
         for( i=0;i<l;i++)
         {
             if(nu[nuy[i].f].f>4)
             {
                 flag=1;
                 break;
             }
             if(nuy[i].x==fx&&nuy[i].y>fy)
             {
                 fy=nuy[i].y-1;
                 nu[nuy[i].f].f++;
                 t++;
                 d=1;
                 break;
             }
         }
         if(i>=l||i<0)
         flag=2;
     }    
    if(flag!=0)
    break;
}
    
    if(flag==1)
    printf("-1
");
    else
    printf("%d
",t);
    for( i=0;i<l;i++)        //初始化 
    {
        nu[i].f=0;nu[i].x=0;nu[i].y=0;
        nux[i].f=0;nux[i].x=0;nuy[i].y=0;
        nuy[i].f=0;nuy[i].y=0;nux[i].x=0;
    }
}
    return 0;        
}
View Code
前段时间又遇到了这道题,做起来也顺手许多,附代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
const int M = 1111;
struct nod{
    int x;
    int y;
}nd[M];
int book[M];
int main(){
    int n;
    while(~scanf("%d",&n)){
    	memset(book,0,sizeof(book));
        for(int i=0;i<n;i++){
            scanf("%d %d",&nd[i].x,&nd[i].y);
        }
        int d=1,fx=0,fy=0,maxx=-inf,minn=inf,f=0,cnt=0,end=0,mi;
        while(1){
            maxx=-inf,minn=inf,f=0;
            if(d==1){
                for(int i=0;i<n;i++){
                    if(nd[i].y==fy&&nd[i].x>fx&&nd[i].x<minn){
                        minn=nd[i].x; f=1;  mi=i;
                    }
                }
                if(f){
                    fx=minn-1; d=2;
                    book[mi]++;
                    cnt++;
                    if(book[mi]>4) {
                    	end=1; break;
                    }
                }
                else break;
            }
            else if(d==2){
                for(int i=0;i<n;i++){
                    if(nd[i].x==fx&&nd[i].y<fy&&nd[i].y>maxx){
                        maxx=nd[i].y;f=1;  mi=i;
                    }
                    
                }
                if(f){
                    fy=maxx+1; d=3;
                    book[mi]++;
                    cnt++;
                    if(book[mi]>4) {
                    	end=1; break;
                    }
                }
                else break;
            }
            else if(d==3){
                for(int i=0;i<n;i++){
                    if(nd[i].y==fy&&nd[i].x<fx&&nd[i].x>maxx){
                    	maxx=nd[i].x;f=1;  mi=i;
                    }
                }
                if(f){
                	fx=maxx+1; d=4;
                	book[mi]++;
                	cnt++;
                    if(book[mi]>4) {
                    	end=1; break;
                    }
                }
                else break;
            }
            else if(d==4){
            	for(int i=0;i<n;i++){
            		if(nd[i].x==fx&&nd[i].y>fy&&nd[i].y<minn){
            			minn=nd[i].y; f=1;  mi=i;
            		}
            	}
            	if(f){
            		fy=minn-1; d=1;
            		book[mi]++;
            		cnt++;
                    if(book[mi]>4) {
                    	end=1; break;
                    }
            	}
            	else break;
            }
        }
        if(end==1) printf("-1
");
        else printf("%d
",cnt);
    }
    return 0;
}

  



原文地址:https://www.cnblogs.com/zmin/p/6592065.html