CSU 1756: Prime

来源:互联网 发布:知乎周刊plus重拾英语 编辑:程序博客网 时间:2024/05/17 04:22

题目:

Description

如果a,b的最大公约数是1,说明a,b是一对互素的数,给定你n个数字,希望你找出互素的数的对数

Input

第一行输入一个正整数T,表示数据组数

每组数据第一行输入一个正整数n,表示数字的个数(n<=10000)

接下来一行输入n个正整数,每个数字大小不超过1000

Output

输出互素的数的对数

Sample Input

1410 9 6 35

Sample Output

3
这个题目的输入量是10000,如果用平方的方法的话应该会超时。

虽然这么想着,不过我还是神不知鬼不觉的把代码写出来提交了。

代码:

#include<iostream>#include<string.h>using namespace std;bool f(int a, int b){if (a == 1 || b == 1)return true;if (a == 0 || b == 0)return false;if (a > b)return f(a - b, b);return f(a, b - a);}int list[10000];int main(){int cas;cin >> cas;int sum;while (cas--){int n;cin >> n;memset(list, 0, sizeof(list));for (int i = 0; i < n; i++)cin >> list[i];sum = 0;for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){if (f(list[i], list[j]))sum++;}}cout << sum << endl;}return 0;}

然后果然超时了,3秒果然不够用。

然后只能用计重的方法了,因为每个数都不超过1000。

我想到的计重的方法有2种,第一种是,直接记录从1到1000每个数出现的次数,用1个长1000的数组就可以了。

不过这种方法我并没有实现,因为我觉得方法二更快。

方法二:把10000个数排序,然后计重的同时我们会得到一个有多少个数,

比如如果有100个数的话,后面的步骤就是100个数两两比较,而不是1000个,这样就比较快。

代码:

#include<iostream>#include<string.h>#include<algorithm>using namespace std;bool f(int a, int b){if (a == 1 || b == 1)return true;if (a == 0 || b == 0)return false;if (a > b)return f(a - b, b);return f(a, b - a);}int list[10000];struct node{int a;int num;};int main(){int cas;cin >> cas;int sum;while (cas--){int n;cin >> n;memset(list, 0, sizeof(list));for (int i = 0; i < n; i++)cin >> list[i];sort(list, list + n);node nod[1001];int i = 0, j = 0;nod[0].a = -1;while (i < n){if (list[i] == nod[j].a)nod[j].num++;else{j++;nod[j].a = list[i];nod[j].num = 1;}i++;}sum = 0;for (int i = 1; i <= j; i++){for (int k = i+1; k <= j; k++){if (f(nod[i].a, nod[k].a))sum += nod[i].num*nod[k].num;}}if (nod[1].a == 1)sum += nod[1].num*(nod[1].num - 1) / 2;cout << sum << endl;}return 0;}

这个代码确实过了,然而并不快。

我是1172ms,还有2个人过了,一个是604ms,另外一居然是180ms。

我想了一下,这个方法也有它的缺点,缺点就是排序本身花了大量时间。

总的来说2种计重的方法谁好谁坏是说不清楚的,要看输入的数据的特性。如果输入了10000个数,从1到1000都有,那我这个方法效率就不高了。

还有1个需要注意的地方,如果有1的话,1和1也是互素的,所以我最后加了一句

if (nod[1].a == 1)sum += nod[1].num*(nod[1].num - 1) / 2;

2 0