无专精则不能|

伍六柒-

园龄:3年6个月粉丝:9关注:6

跳跳-题解

cf 1200

题目描述
平面上给定了一些整点(横纵坐标均为整数的点),被称为 “魔法阵”。魔法少女派派想要在各魔法阵之间传送,每一次传送,她将使用下面的方式:

  1. 刚开始,派派已经位于某传送阵之上;
  2. 如果派派掌握一种魔法 (A,B),其中 A,B 均为整数。使用一次这个魔法可以让派派从任意整点 (X,Y) 瞬间移动至 (X+A,Y+B);
  3. 选择一种魔法并开始传送,在一次传送过程中可以使用多次该魔法,但在抵达下一个传送阵之前仅能使用这一种魔法。

问派派至少需要掌握多少种魔法,才能在从任意魔法阵直接传送到任意魔法阵?

题目链接


方法:
在到达下一个魔法阵之前只能使用一种魔法,次数没有限制。总共有n个点对,假设我们从任意一点(x1, y1) 到达任意另一点 (x2, y2) 只使用一次魔法,那么就需要一个法术(x2 - x1, y2 - y1),从(x2, y2) 到达 (x1, y1)需要另一个法术,在此先不考虑,仅考虑“正向”需要的法术,对于任意不同的两点都可以求出一个这样的法术,那么在所有的法术中,有哪些是可以“抵消”的呢?因为一条法术是另一条法术的正整数倍,所以只要比值相同的法术就一定可以用一条“最简比值法术”代替,比如(3,6)和(4,8)虽然他们两个不是倍数关系,但是却可以用“最简比值法术”把他们抵消掉,因此我们的任务就是求比值相同的法术有多少条。前面说先不考虑反向的法术,现在开始考虑,会发现,虽然反向的法术与正向的法术比值相同,但是无法被抵消,因为无法使用负整数次法术,所以只需要考虑正向的然后输出结果的二倍就行了。


代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 510;
vector<double> v;
PII p[N];
int n;
int main() {
cin >> n;
for(int i = 0; i <n; i++)
cin >> p[i].first >> p[i].second;
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i != j) {
if(p[i].first == p[j].first) //即出现了魔法为(0, x)的情况,可以全部用(0, 1)表示,
v.push_back(1e9); // 用1e9 表示比值避免冲突
else
v.push_back(1.0 * (p[j].second - p[i].second)/(p[j].first - p[i].first));
}
}
}
sort(v.begin(), v.end());
v.erase(v.begin(), unique(v.begin(), v.end()));
cout << v.size() * 2 << endl;
return 0;
}

本文作者:伍六柒-

本文链接:https://www.cnblogs.com/paper-plane/p/15991120.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   伍六柒-  阅读(51)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开