看似数学题 (思维)

本文链接:https://blog.csdn.net/weixin_43880627/article/details/100567452
       
 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

————————————————
版权声明:本文为CSDN博主「刘健铭wawawawa」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43880627/article/details/100567452
 
posted @ 2019-09-05 22:03  jjjjjjjjm  阅读(149)  评论(0编辑  收藏  举报