题目描述
众所周知,度度熊最近沉迷于 Pokémon GO。
由于太过沉迷,现在它只能按照游戏内置的指令行走了:对,简直就像一个现实中的Pokémon!
游戏内置的指令实际上可以抽象成一种:保持现在的朝向前行X米,然后右转。度度熊相信,只要遵循这个指令,它就一定可以抓到最珍奇的精灵球。
但不幸的是,这个指令并不是很有可信度,有时会引导度度熊走回原来的位置。现在它想知道,在第几条指令时它第一次回到已经走过的位置?如果这种情况没有发生,请输出 “Catch you”。
解题思路
最开始的想法就是把线段搞一起,判断是否相交,但是无论怎么优都是带log的,显然超时。
仔细观察题目,每次转动的方向是确定的,必然存在某种规律。
通过画图可以发现,只有以下三种相交方式。
所以对于新加的线段只需要判断它与它的前4,5,6条线段是否相交就可以了。
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
char readc(){
static char buf[100000], *l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF;else return *l++;
}
inline int _read(){
int num=0;char ch=readc();
while (ch<'0'||ch>'9') ch=readc();
while (ch>='0'&&ch<='9') num=num*10+ch-48,ch=readc();
return num;
}
struct jz{
LL x1,y1,x2,y2;
}a[1000005];
int t,n,ans;
bool check(int x,int y){
if (a[x].x1!=a[x].x2) swap(x,y);
if (a[x].y1<=a[y].y1&&a[y].y1<=a[x].y2&&a[y].x1<=a[x].x1&&a[x].x1<=a[y].x2) return 1;
return 0;
}
void work(){
n=_read();
LL x=0,y=0;ans=-1;
for (int i=1;i<=n;i++){
int w=_read();
if (ans!=-1) continue;
if ((i+1)/2%2==1) w=-w;
a[i].x1=x;a[i].y1=y;
if (i%2==1) x+=w;else y+=w;
a[i].x2=x;a[i].y2=y;
if (a[i].y1>a[i].y2) swap(a[i].y1,a[i].y2);
if (a[i].x1>a[i].x2) swap(a[i].x1,a[i].x2);
if ((i>=4&&check(i,i-4+1))||(i>=6&&check(i,i-6+1))) ans=i;
}
if (ans==-1) printf("Catch you\n");else printf("%d\n",ans);
}
int main(){
freopen("exam.in","r",stdin);
freopen("exam.out","w",stdout);
t=_read();
while(t--) work();
return 0;
}