题目大意:
平面上有
个点,初始任意两个点距离
,点
有一个值
。
所有点同时开始移动,点
的运动速率为
单位/秒,方向为它到点
连线方
向(点
与点
重合的话点
此刻将不会移动)。
如果某时刻点
与点
距离为
或这个时刻之前的
秒内点
与点
距离保持不变,则自该时刻起点
的运动方向将变为恒与点
相同。
如果点
的运动方向不是它到点
连线方向而是恒与点
本身相同(取决于点
本身),则称点
“不知道向哪里移动”。求经过无限长的时间后的任意一组运动方向相同的“不知道向哪里移动”的点。另外如果一个点“不知道向哪里移动”,它将不动。
分析:
真实题目实在是,实在是,,,太exin了 (疯狂吐槽)
注意到一个点
“不知道向哪里移动”当且仅当
。此时点
所属的一组“不知道向哪里移动”的点为
。所以可以
枚举点
,看
是否
,如果一直到
都不等于
或一直到
都不等于
且
,那么点
不可能“不知道向哪里移动”。找到第一个“不知道向哪里移动”的点后即可输出该点所。.
在此基础上,如果找到
,则
“不知道向哪里移动”。根据抽屉原理,
中必有两个数相等,所以任取点
即可找到一个“不知道向哪里移动”的点。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
#define N 200005
using namespace std;
int lovenum[N], first[N], huan[N], cnt, n;
bool vis[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &lovenum[i]);
int x, y;
for (int i = 1; i <= n; i++) scanf("%d%d",&x, &y);
int Number = 1;
while (!vis[Number])
{
vis[Number] = 1;
huan[++cnt] = Number;
first[Number] = cnt;
Number = lovenum[Number];
if (vis[Number])
{
printf("%d\n", cnt - first[Number] + 1);
for (int i = first[Number]; i <= cnt; i++) printf("%d ", huan[i]); printf("\n");
}
}
return 0;
}