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. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  2. [从源码学设计]蚂蚁金服SOFARegistry之延迟操作

    [从源码学设计]蚂蚁金服SOFARegistry之延迟操作 0x00 摘要 SOFARegistry 是蚂蚁金服开源的一个生产级.高时效.高可用的服务注册中心. 本系列文章重点在于分析设计和架构,即利 ...

  3. torch.optim.SGD()各参数的解释

    看pytorch中文文档摘抄的笔记. class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, neste ...

  4. Let’s Encrypt/Certbot移除/remove/revoke不需要的域名证书

    1.首先确认你的证书不再需要,如果有必要,请执行下面的命令进行备份 cp /etc/letsencrypt/ /etc/letsencrypt.backup -r 2.撤销证书然后删除证书 [root ...

  5. 解决 win10 无法安装VS2019,visual studio installer下载进度始终为0

    解决 win10 无法安装VS2019,visual studio installer下载进度始终为0 目录 解决 win10 无法安装VS2019,visual studio installer下载 ...

  6. c#使用谷歌身份验证GoogleAuthenticator

    此功能相当于给系统加了个令牌,只有输入对的一组数字才可以验证成功.类似于QQ令牌一样. 一丶创建最核心的一个类GoogleAuthenticator 此类包含了生成密钥,验证,将绑定密钥转为二维码. ...

  7. BI学习向导文章

    BI的学习笔记: BIWORK的博客:http://www.cnblogs.com/biwork/p/3328879.html 邀月工作室博客 :http://www.cnblogs.com/down ...

  8. 阿里巴巴微服务与配置中心技术实践之道 配置推送 ConfigurationManagement ConfigDrivenAnyting

    阿里巴巴微服务与配置中心技术实践之道 原创: 坤宇 InfoQ 2018-02-08 在面向分布式的微服务系统中,如何通过更高效的配置管理方式,帮助微服务系统架构持续"无痛"的演进 ...

  9. 翻页bug 在接口文档中应规范参数的取值区间 接口规范

    <?php$a=array("red","green","blue","yellow","brown&q ...

  10. TCMalloc源码学习(四)(小内存块释放)

    pagemap_和pagemap_cache_ PageHeap有两个map,pagemap_记录某一内存页对应哪一个span,显然可能多页对应一个span,pagemap_cache_记录某一内存页 ...