您的位置:首页 > 其它

k.计软联谊 「游族杯」上海市高校程序设计邀请赛(数论)

2017-05-31 22:42 260 查看


K. 计软联谊

Time limit per test: 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

input
2
3 1
4 6 12
6 2
13 12 12 24 36 30


output
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>中找出 a,b 第 k 大的公约数

代码:

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐