K. 计软联谊
Time limit per test: 7.0 seconds
Memory limit: 512 megabytes
Accept / Submit: 19 / 398
在计算机和软件专业的联谊会上,计算机和软件的同学相间着排成一列。现在要计算相邻两个同学的友谊度。
友谊度
Input
第一行是数据组数
对于每组数据:
第一行:首先是学生的数量
第二行:
Output
对于每组数据输出一行,以 Case x:
开头(x 表示数据编号,从 1 开始),后面是
Examples
input2output
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
请注意输入输出上的优化!
想法:
首先找出1到10^6的因数,最好用<vector>保存
该步骤的代码:
void init()//找每个数的因数
{
for(int i = 1;i<=L;i++)
{
for(int j = i;j<=L;j+=i)
{
P[j].push_back(i);
}
}
}
再者我们要用欧几里得找出最大公约数
这样我们很容易从<vector>中找出
代码:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
const int L = 1e6;
int m[maxn];
vector <int > P[L+1];
int kase = 1;
void init()//找每个数的因数
{
for(int i = 1;i<=L;i++)
{
for(int j = i;j<=L;j+=i)
{
P[j].push_back(i);
}
}
}
int gcd(int a, int b)//找a和b的最大公约数
{
return b==0?a:gcd(b, a%b);
}
void solve()
{
int n, k;
scanf("%d%d", &n, &k);
for(int i = 1;i<=n;i++)
scanf("%d", &m[i]);
printf("Case %d:", kase++);
for(int i = 1;i<n;i++)
{
int x = gcd(m[i], m[i+1]);//两个相邻同学的属性值的最大公约数
int len = P[x].size();
if(len-k>=0)
{
printf(" %d", P[x][len-k]);
}
else
printf(" -1");
}
printf("\n");
}
int main()
{
init();
int T;
scanf("%d", &T);
while(T--)
{
solve();
}
return 0;
}