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