题目链接:http://acm.ecnu.edu.cn/contest/16/problem/K/
题目:
K. 计软联谊
Time limit per test: 7.0 seconds
Time limit all tests: 7.0 seconds
Memory limit: 512 megabytes
Accept / Submit: 19 / 398
在计算机和软件专业的联谊会上,计算机和软件的同学相间着排成一列。现在要计算相邻两个同学的友谊度。
友谊度 friend(a,b) 是这么计算的:令 a, b 两个整数分别是两个同学的属性,两个同学的友谊度取决于 a,b 第 k 大的公约数。如果不存在,就说明这两个同学之间完全没有友谊,友谊度为 −1。
Input
第一行是数据组数 T (1≤T≤60)。
对于每组数据:
第一行:首先是学生的数量 n (1≤n≤105),约定的常数 k (1≤k≤106)。
第二行:n 个整数,依次表示这些学生的属性值:m1,m2,…,mn (1≤mi≤106)。
Output
对于每组数据输出一行,以 Case x:
开头(x 表示数据编号,从 1 开始),后面是 n−1 个整数,分别是 friend(m1,m2),friend(m2,m3),…,friend(mn−1,mn),整数和整数之间用空格隔开。
Examples
2 3 1 4 6 12 6 2 13 12 12 24 36 30
Case 1: 2 6 Case 2: -1 6 6 6 3
Note
请注意输入输出上的优化!
题解:
就每两个数gcd,求出最大公约数。然后求第k大的公约数。
一开始理解错,以为第2大的公约数是最大公约数除以2,第3大则是除以4。dalao说是错的。
第k大的公约数是最大公约数的约数(不一定是除以2,可以除以3什么的)。
就先用筛法将1~1e6的每个数的约数筛出来。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 void init() { 2 for(int i = 1;i<=L;i++){ 3 for(int j = i;j<=L;j+=i){ 4 P[j].push_back(i); 5 } 6 } 7 }
详细代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <string> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <algorithm> 14 using namespace std; 15 #define pb push_back 16 #define mp make_pair 17 #define ms(a, b) memset((a), (b), sizeof(a)) 18 #define eps 0.0000001 19 typedef long long LL; 20 typedef unsigned long long ULL; 21 const int inf = 0x3f3f3f3f; 22 const LL INF = 0x7fffffff; 23 const int maxn = 1e5+10; 24 const int L = 1e6; 25 const int mod = 1e9+7; 26 int m[maxn]; 27 vector <int > P[L+1]; 28 int kase = 1; 29 void init() { 30 for(int i = 1;i<=L;i++){ 31 for(int j = i;j<=L;j+=i){ 32 P[j].push_back(i); 33 } 34 } 35 } 36 int gcd(int a, int b){ 37 return b==0?a:gcd(b, a%b); 38 } 39 void solve() { 40 int n, k; 41 scanf("%d%d", &n, &k); 42 for(int i = 1;i<=n;i++) 43 scanf("%d", &m[i]); 44 printf("Case %d:", kase++); 45 for(int i = 1;i<n;i++){ 46 int x = gcd(m[i], m[i+1]); 47 int len = P[x].size(); 48 if(len-k>=0){ 49 printf(" %d", P[x][len-k]); 50 } 51 else 52 printf(" -1"); 53 } 54 printf("\n"); 55 } 56 int main() { 57 #ifdef LOCAL 58 freopen("input.txt", "r", stdin); 59 // freopen("output.txt", "w", stdout); 60 #endif // LOCAL 61 init(); 62 int T; 63 scanf("%d", &T); 64 while(T--){ 65 solve(); 66 } 67 return 0; 68 }
你努力的时候,比你厉害的人也在努力。