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


题意:青蛙在迷宫里面一直向前走,如果遇到障碍,就原地向右转,然后继续向前走。能走出迷宫,输出转向次数。
走不出去,输出-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\n");
else
printf("%d\n",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;
}
前段时间又遇到了这道题,做起来也顺手许多,附代码:
#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\n");
else printf("%d\n",cnt);
}
return 0;
}

  



scu-4445的更多相关文章

  1. 模拟+贪心 SCU 4445 Right turn

    题目传送门 /* 题意:从原点出发,四个方向,碰到一个点向右转,问多少次才能走出,若不能输出-1 模拟:碰到的点横坐标相等或纵坐标相等,然而要先满足碰到点最近, 当没有转向或走到之前走过的点结束循环. ...

  2. SCU 4445 Right turn(dfs)题解

    思路:离散化之后,直接模拟就行,标记vis开三维 代码: #include<iostream> #include<algorithm> #include<cstdio&g ...

  3. SCU 4445 Right turn

    模拟. 每次找一下即将要遇到的那个点,这个数据范围可以暴力找,自己的写的时候二分了一下.如果步数大于$4*n$一定是$-1$. #include<bits/stdc++.h> using ...

  4. ACM:SCU 4437 Carries - 水题

    SCU 4437  Carries Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practice  ...

  5. ACM: SCU 4438 Censor - KMP

     SCU 4438 Censor Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practice D ...

  6. ACM: SCU 4440 Rectangle - 暴力

     SCU 4440 Rectangle Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practic ...

  7. SCU 4424(求子集排列数)

    A - A Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice ...

  8. SCU 2941 I NEED A OFFER!(01背包变形)

    I NEED A OFFER!     64bit IO Format: %lld & %llu Submit Status Description Description Speakless ...

  9. SCU 4440 分类: ACM 2015-06-20 23:58 16人阅读 评论(0) 收藏

    SCU - 4440 Rectangle Time Limit: Unknown   Memory Limit: Unknown   64bit IO Format: %lld & %llu ...

  10. scu 4436: Easy Math 水题

    4436: Easy Math Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.scu.edu.cn/soj/problem.actio ...

随机推荐

  1. 1.8V转5V电平转换芯片,1.8V转5V的电源芯片

    1.8V是一个比较低的电压,在电压供电电压中,1.8V电压的过于小了,在一些电子模块或者MCU中,无法达到供电电压,和稳压作用,PW5100就是可以在1.8V转5V的电平转换电路和芯片,最大可提供50 ...

  2. windows上传ipa到苹果开发者中(app store)的方法

    假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开发者中心才能在构建版本里选择构建版本上架 ...

  3. 【Android初级】使用Gallery实现照片拖动的特效(附源码)

    今天要分享一个非常简单的功能: 使用Android原生控件Gallery实现照片拖动的特效 实现思路如下: 在布局文件中定义一个Gallery控件 由于要显示多张图,为了方便,我直接引用了Androi ...

  4. Flink的状态与容错

    本文主要运行到Flink以下内容 检查点机制(CheckPoint) 状态管理器(StateBackend) 状态周期(StateTtlConfig) 关系 首先要将state和checkpoint概 ...

  5. 前端面试准备笔记之JavaScript(03)

    01. 变量声明提升 在预解析的时候,成员变量和函数,被提升到最高的位置,方便其他程序访问. 可以先使用后声明. 只提升变量名,不提升变量值 let const 声明的变量不具有变量声明提升. // ...

  6. 如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  7. RabbitMq消费者在初始配置之后进行数据消费

    RabbitMq消费者在初始配置之后进行数据消费 问题背景 在写一个消费rabbitmq消息的程序是,发现了一个问题,消费者的业务逻辑里面依赖这一些配置信息,但是当项目启动时,如果队列里面有积压数据的 ...

  8. Edition-Based Redefinition

    Oracle在11g引入了Edition-Based Redefinition(EBR),主要是为了解决在更新数据库对象,比如PL/SQL程序,视图等,如果该对象被锁住了,会导致更新必须等待,如果要使 ...

  9. java-数据类型复习

    java中共有8种基本的数据类型,分别为 字节型byte(8字节,32位),短整型short(16字节),整型int(32字节),长整型long(64字节), 字符型char(16字节),浮点型flo ...

  10. https://github.com/golang/go/wiki/CommonMistakes

    CommonMistakes https://golang.org/doc/faq#closures_and_goroutines Why is there no goroutine ID? ¶ Go ...