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. online创建索引中途取消导致索引无法删除解决办法

    问题:有一个表ID栏位没有索引,但是在一个update语句的where中被使用,因此打算online创建索引,但是长时间没有成功,此时决定取消,取消后发现索引无法删除 过程: 数据库监控报警有行锁,进 ...

  2. 【对线面试官】Java多线程基础

    // 请求直接交给线程池来处理 public void push(PushParam pushParam) { try { pushServiceThreadExecutor.submit(() -& ...

  3. Entity与Entity之间的相互转化

    一.两个实体类的属性名称对应之间的转化 1.两个实体类 public class Entity1 { private Integer id; private String name; private ...

  4. 面向对象的延伸与Java内部定义类的应用

    识别类 传统的过程化程序设计,必须从顶部的main函数开始编写程序,在面向对象程序设计时没有所谓的"顶部".首先从设计类开始,然后再往每个类中添加方法. 识别类的规则是在分析问题的 ...

  5. 抽取一部分服务端做BFF(Backend For Frontend服务于前端的后端)

    Flutter+Serverless端到端研发架构实践 · 语雀 https://www.yuque.com/xytech/flutter/kdk9xc 2019-12-19 13:14 作者:闲鱼技 ...

  6. Object level permissions support

    django-guardian (1.1.1+) - Object level permissions support. Home - Django REST framework https://ww ...

  7. Java内存溢出处理

    在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识. jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区 ...

  8. sql多行合并

    例一 SELECT qqo.questionID '题目id', qqo.quesOption '选项' FROM qz_question_option qqo, qz_question qq WHE ...

  9. 你真的知道为什么要使用void(0)代替undefined吗?

    我们平时用到的\(\color{#FF3030}{undefined}\)只是\(\color{#FF3030}{window}\)对象下的一个属性. Object.getOwnPropertyDes ...

  10. Kepware软件基本操作及使用Java Utgard实现OPC通信

    一.环境搭建(基于win10 64位专业版) 1.Kepware 的下载.安装及使用 https://www.cnblogs.com/ioufev/p/9366877.html 2.重要:OPC 和 ...