LightOJ 1370 Bi-shoe and Phi-shoe-----数论

Time limit  2000 ms

Memory limit  32768 kB

OS  Linux

Source  Problem Setter: Mir Wasi Ahmed

             Special Thanks: F.A. Rezaur Rahman Chowdhury, Jane Alam Jan

Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe is a very popular coach for his success. He needs some bamboos for his students, so he asked his assistant Bi-Shoe to go to the market and buy them. Plenty of Bamboos of all possible integer lengths (yes!) are available in the market. According to Xzhila tradition,

Score of a bamboo = Φ (bamboo's length)

(Xzhilans are really fond of number theory). For your information, Φ (n) = numbers less than n which are relatively prime (having no common divisor other than 1) to n. So, score of a bamboo of length 9 is 6 as 1, 2, 4, 5, 7, 8 are relatively prime to 9.

The assistant Bi-shoe has to buy one bamboo for each student. As a twist, each pole-vault student of Phi-shoe has a lucky number. Bi-shoe wants to buy bamboos such that each of them gets a bamboo with a score greater than or equal to his/her lucky number. Bi-shoe wants to minimize the total amount of money spent for buying the bamboos. One unit of bamboo costs 1 Xukha. Help him.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 10000) denoting the number of students of Phi-shoe. The next line contains n space separated integers denoting the lucky numbers for the students. Each lucky number will lie in the range [1, 106].

Output

For each case, print the case number and the minimum possible money spent for buying the bamboos. See the samples for details.

Sample Input

3

5

1 2 3 4 5

6

10 11 12 13 14 15

2

1 1

Sample Output

Case 1: 22 Xukha

Case 2: 88 Xukha

Case 3: 4 Xukha

题解:竹竿的分数=Φ (竹竿的长度):意思定义一个长度为n的竹竿,那么Φ (n)=从1~n的所有数中n的相对素数(除了1以外没有公约数)的个数。例如:Φ (10)=4(1,3,7,9)其中与10有公约数的数字为:2,4,5,6,8,10。然后我们可以将n为1~11的情况列举出来:

n=2:  1-----------------------------------------------------------------1+1=2

n=3:  1、2------------------------------------------------------------2+1=3

n=4:  1、3------------------------------------------------------------2;

n=5:  1、2、3、4---------------------------------------------------4+1=5

n=6:1、5------------------------------------------------------------2;

n=7:1、2、3、4、5、6-----------------------------------------6+1=7

n=8:  1、3、5、7---------------------------------------------------4;

n=9: 1、2、4、5、7、8----------------------------------------6;

n=10:  1、3、7、9-----------------------------------------------4;

n=11:  1、2、3、4、5、6、7、8、9、10-----------------10+1=11

题目要求是给出幸运分数要求最短的长度,由这些例子可以看出幸运分数对应的最短长度只有可能是大于等于幸运分数+1的最小素数。为了避免时间复杂度过高,我们不能再主函数里面定义两个for镶嵌在一起求和,我采用的是在打表过程中将小于等于某一素数的数都定义为该素数,例如prim[4]=5;prim[9]=11。

#include <iostream>
#include <string.h>
#define ll long long
#define maxn 1000005
using namespace std;
int prime[maxn];
int prim[maxn];
bool isprime[maxn];
int a[10005];
void query()   //首先将所有素数打表一遍
{
    int total=0;
    memset(isprime,true,sizeof(isprime));
    memset(prime,0,sizeof(prime));
    isprime[1]=false;
    for(int i=2;i<=maxn;i++)
    {
        if(isprime[i])prime[total++]=i;
        for(int j=0;j<total&&i*prime[j]<=maxn;j++)
        {
            isprime[i*prime[j]]=false;
            if(i%prime[j]==0)break;
        }
    }
    int d=0;
    for(int i=1;i<=maxn;i++)     //将小于等于某一素数的那一段数全部定义为改素数
    {
        if(isprime[i]){prim[i]=prime[d];d++;}
        else prim[i]=prime[d];
    }
}
int main()
{
    int t,n;
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>t;
    query();
    int s=0;
    while(t--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i];
        ll sum=0;
        for(int i=0;i<n;i++)
        {
            sum+=prim[a[i]+1];
        }
        cout<<"Case "<<++s<<": "<<sum<<" Xukha"<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_41233888/article/details/81291217