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 (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的更多相关文章
- 模拟+贪心 SCU 4445 Right turn
题目传送门 /* 题意:从原点出发,四个方向,碰到一个点向右转,问多少次才能走出,若不能输出-1 模拟:碰到的点横坐标相等或纵坐标相等,然而要先满足碰到点最近, 当没有转向或走到之前走过的点结束循环. ...
- SCU 4445 Right turn(dfs)题解
思路:离散化之后,直接模拟就行,标记vis开三维 代码: #include<iostream> #include<algorithm> #include<cstdio&g ...
- SCU 4445 Right turn
模拟. 每次找一下即将要遇到的那个点,这个数据范围可以暴力找,自己的写的时候二分了一下.如果步数大于$4*n$一定是$-1$. #include<bits/stdc++.h> using ...
- ACM:SCU 4437 Carries - 水题
SCU 4437 Carries Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practice ...
- ACM: SCU 4438 Censor - KMP
SCU 4438 Censor Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practice D ...
- ACM: SCU 4440 Rectangle - 暴力
SCU 4440 Rectangle Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Practic ...
- SCU 4424(求子集排列数)
A - A Time Limit:0MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice ...
- SCU 2941 I NEED A OFFER!(01背包变形)
I NEED A OFFER! 64bit IO Format: %lld & %llu Submit Status Description Description Speakless ...
- SCU 4440 分类: ACM 2015-06-20 23:58 16人阅读 评论(0) 收藏
SCU - 4440 Rectangle Time Limit: Unknown Memory Limit: Unknown 64bit IO Format: %lld & %llu ...
- scu 4436: Easy Math 水题
4436: Easy Math Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.scu.edu.cn/soj/problem.actio ...
随机推荐
- 未使用绑定变量对share_pool的影响
oracle SGA中包含数据高速缓冲,重做日志缓冲,以及共享池(share_pool).共享池中包含库高速缓冲(所有的SQL,执行计划等)和数据字典缓冲(对象的定义,权限等). 所以,如果SQL中没 ...
- the7主题 一个强大的wordpress 主题 html5拖拽式建站系统
演示地址 http://the7.net The7汉化主题.可视化编辑器和终极交互式模块插件完全无缝集成,可以让你完全自由的布局或者创意实现你的网站,真正的建站仿站利器. The7的750+个主题设置 ...
- Java异常处理场景中不同位置的返回值详细解析
Java 异常处理中的返回值在不同位置不同场景下是有一些差别的,这里需要格外注意 具体分以下两种场景: 1 finally语句块没有return语句,即当代码执行到try或者catch语句块中的ret ...
- 企业项目迁移go-zero全攻略(二)
承接上篇:上篇文章讲到 go-zero 架构设计和项目设计.本篇文章接着这个项目设计,将生成的 app 模块 中 gateway 和 RPC 进行改造.废话不多说,让我们开始! gateway ser ...
- websocket的应用---Django
websocket的应用---Django 1.长轮询 轮询:在前端通过写js实现.缺点:有延迟.服务器压力大. 就是客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的 ...
- 让绝对定位的div居中
最近看到一个问题就是让绝对定位的div居中,在尝试了top:50%:left:50%:后发现,居中是有问题的并不是想象中的样子 需要再加两句margin-top:-盒子高度的一般px margin- ...
- (008)每日SQL学习:Oracle Not Exists 及 Not In 使用
今天遇到一个问题,not in 查询失效,我以为是穿越了,仔细查了点资料,原来理解有误! select value from temp_a a where a.id between 1 and 100 ...
- WPF排版布局经验总结(干货)简短不疲倦
本文不过多讲述wpf的基础布局控件,本文只记录WPF排版的技巧,这是个人的总结,不能符合所有情况,如果有何不对的地方,请评论指正,谢谢. 1.区域划分 在接手一个界面的时候,先纵观全局,将眼见的区域划 ...
- deepin定制deepin-terminal
一. 背景介绍 本人以前在win10上经常使用xshell来登陆服务器.xshell提供了很丰富的功能和快捷键.个人比较喜欢的包括三个功能 终端透明 双击时根据分隔符选中文字 突出显示 但是自从使用d ...
- php中两个函数可能导致的sql注入
sprintf https://www.php.net/manual/zh/function.sprintf.php 漏洞demo: <?php $name = addslashes($_GET ...