【五校联考2day2】互相追逐的点

额,这道题是五校联考2day2的第2题

一开始还真是看不懂。

原题目描述得又臭又长,又繁琐,又难懂。(这出题人是个吹水的好苗子啊。。。囧。。。真会坑人)读了半天,才明白了题目的大意是这样的:

Description:

有 n 个互相追逐的点 ( 1≤n≤20000 ),每个点 i 都有它自己的目标点 A[i](注意 A[i] 为给出的 n 个点中的一个)。已知每个点的初始坐标,开始计时后,每单位时间它们会向各自的目标点移动 1 单位距离。
  当点 i 距离它的目标点只有 1 单位距离、或者它与目标点的距离在 1 单位时间内保持不变时,它会跟随它的目标点向同一方向移动(即它的移动方向由它的目标点决定)。我们称一个点“不知道自己的移动方向”当且仅当它的移动方向由它自己决定(注意如果一个点的移动方向决定于一个“不知道自己的移动方向”的点的移动方向,那么它不能算是“不知道自己的移动方向”)。一个“不知道自己的移动方向”的点会停下不动。
  现在询问的是:在过了无限长的时间后,任意一组“不知道各自的移动方向”的点。输出任意一组且不要求输出顺序。

真是无语了。。。题目那么长,其实做起来却很简单——就是要我们求环!!因为如果一个点追着目标点,一直在追的话,有无限长的时间,那么他们就一定会慢慢聚拢在一起,最终停下,达成目标状态。那么这就很明显地看出了这分明就是要我们找环吗!
我们可以输入的每个点向他的目标点连条边,并通过搜索找出第一次出现环的情况。
并用数组存下想对应的状态,最后输出找到的状态就行了。(友情提示:递归会爆栈,要改成while循环或更优的找法。。更优的方法是什么我就不多说了,要是觉得好奇,可以自己想想)

代码程序实现起来很简单

For example:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define N 200008
#define fo(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
int n,a[N],b[N],c[N],wz[N][3],tot=0;
int Find_Huan(int x)
{
    while (!b[x])
    {
        b[x]=++tot;
        c[tot]=x;
        x=a[x];
    }
    return x;
}
int main()
{
    scanf("%d",&n);
    fo(i,1,n) scanf("%d",&a[i]);
    fo(i,1,n) scanf("%d%d",&wz[i][1],&wz[i][2]);
    int x=Find_Huan(1);
    printf("%d\n",tot-b[x]+1);
    fo(i,b[x],tot) printf("%d ",c[i]);
    return 0;
}

这道题告诉我们,有时候题目很繁琐的时候,我们要学会整理条件并找出有用的条件,筛掉无用的条件,让自己思路更清晰

遇到这种看似难题的时候,不能轻易放弃,要坚持想方法,要相信就算是水法,也一定可以骗分的。说不准你的水法就是这道题的正解呢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值