其他分享
首页 > 其他分享> > 看似数学题 (思维)

看似数学题 (思维)

作者:互联网

Description

给定一个数组A,长度为N。
给一个整数K,你需要找到满足如下条件数组B:
1、数组长度也是N;
2、数组中每个数字都是不超过K的正整数;
3、存在两个正整数X和Y,使得A[i] * X == B[i] * Y 对所有1<=i<=N都成立。
求出满足这样条件的数组的个数。

Input

第一行两个整数N和K。
第二行N个整数,表示数组A。
数据范围:
1 <= N <= 2e5
1 <= K, A[i] <= 1e18

Output

输出一个数字,表示答案。

Sample Input 1

3 10
4 6 8

Sample Output 1

2

如标题的括号所示,这道题其实只是道思维题,写下这篇文,主要是想提醒自己以后类似的题目,思维要转快一点。
题目的A[i] * X == B[i] * Y很显然说明了数组A和B是一堆成比例关系的数组,所以只需要求出在k的范围内可以构成的B的个数,即求范围内的比例数。
一开始的思路是先求出比例小于1的数,也就是求gcd,然后再求数组A的最大值与k的比例。
但更好的思路应该是先用最大值除以gcd,然后直接被k除,就可以得出B的个数。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll k,a[200005],maxn=0;

ll gcd(ll a,ll b){
	return a == 0 ? b : gcd(b % a, a);
}

int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		maxn=maxn>a[i]?maxn:a[i];
	}
	ll x=a[1];
	for(int i=2;i<=n;i++){
		x=gcd(x,a[i]);
	}
	x=maxn/x;
	cout<<k/x<<endl;
	return 0;
	
}

题源:
http://www.lpoj.cn/contest/45

其实写这篇文的理由还有一个,就是这道题让我想起了ccpc网络赛里的钓鱼题,看到很多题解说什么深搜之类,代码写得老长的,其实只需在输入的时候把大于钓鱼时间的煮鱼时间mod钓鱼时间,然后再丢进数组,那么!!数组内的数都是小于钓鱼时间的!然后排个序就ok了。
待会再去把钓鱼的博客给敲了,又可以水一篇文,美滋滋ヘ(_ _ヘ)

钓鱼网址 比赛题目网址:
http://acm.hdu.edu.cn/showproblem.php?pid=6709

标签:思维,gcd,钓鱼,int,ll,maxn,数组,数学题,看似
来源: https://blog.csdn.net/weixin_43880627/article/details/100567452