[海豹海边爆]Daimayuan496

原题链接:跳跳 - 题目 - Daimayuan Online Judge

解题思路:因为本题的魔法必须是由两个整数构成,所以可以用一对魔法移动的,也就是说他们的x和y的改变量的绝对值,在除以他们的最大公因数后必定相等(比如3,2和6,4可以互通,他们都除以自己的最大公因数后得到的都是3,2)。

也就是说,只要记录一个方向的魔法,并且保证每个魔法的x和y都互质,即步长最小,那么之后能通过的点,必定是这个魔法执行整数次的结果。那么对于每两个点之间差的绝对值,除以他们的最大公因数后,就可以去查找原本的魔法中是否有一样的数值。原本的魔法可以支持这两个点的相互移动,则必然有相同的一对数字。而如果没有,则入队。

最终输出答案时要乘2,因为我们只记录了单向移动的魔法。

AC代码:

#include<bits/stdc++.h>
using namespace std;
long long x[510],y[510],n;
vector<long long> mx;
vector<long long> my;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){//输入 
		scanf("%lld %lld",&x[i],&y[i]);
	}
	
	for(int i=0;i<n-1;i++){//查找,两重循环保证每个点两两之间都配对一次 
		for(int j=i+1;j<n;j++){//从i+1开始防止记录自己到自己 
			long long dx,dy,bk=1;
			bool flag=1;//记录这两个点之间的移动是否需要新的魔法 
			dx=abs(x[i]-x[j]);//记录差的绝对值 
			dy=abs(y[i]-y[j]);
			
 			if(dx!=0&&dy!=0){//如果都不是0,则求他们的最大公因数,然后除以他们本身,得到能连接两点且步长最小的魔法 
    			bk=__gcd(dx,dy);
            	dx/=bk;
    			dy/=bk;
 			}
 			else{//如果有为0的,则不为0的那一个步长最小必定为1 
				if(dx!=0) dx=1;
				if(dy!=0) dy=1;
 			}
			
			for(int k=0;k<mx.size();k++){//循环查找是否以前有过该魔法 
				if(dx==mx[k]&&dy==my[k]){//如果有则直接标记并退出 
					flag=0;
					break;
				}
			}
			
			if(flag){//如果不是提前退出则flag默认1,添加该魔法 
				mx.push_back(dx);
				my.push_back(dy);
			}
		}
	}
	cout<<mx.size()*2;//因为是往返所以要乘以二 
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值