其他分享
首页 > 其他分享> > (数论选拔)联盟阵容

(数论选拔)联盟阵容

作者:互联网

瓦罗兰大陆有n个英雄,他们编号从1到n,每个英雄的战斗力等于他的编号。

某一天这些英雄们准备建立k个联盟,编号为1到k,每个英雄只能加入一个联盟。

每个联盟的战斗力等于它里面的所有英雄的战斗力之和。

但是英雄们都很傲娇,他们想让自己的联盟的战斗力是一个质数,而且他们想让kk尽可能小。

如果他们能按照自己的心意建立联盟,就输出k和这k个联盟的战斗力。

如果有多种情况可以满足他们的心意,就输出让联盟的最小战斗力最小的哪一种。

   例子:

        假设两种情况[2,4,7]  ,  [3,4,6] 都满足条件,由于方案一 种最小的联盟的战斗力是2,小于方案二种的3, 

        所以应该输出 2 , 4,7

否则输出-1.

Input

一个数nn 

nn  <=3000

 

Output

如果n==0或者无解,输出-1.

否则 

 一个整数代表联盟的数量kk

  然后nn个整数代表从小到大依次输出他们的战斗力

Samples

Input 复制
5
Output
2
2 13

Source

2021年昆明区域赛选拔【数论】

 

这个题就是1到n每一个数都可以加入一个阵营,最后k个阵营,每个阵营的和都是素数,问最少要几个阵营

 

这个题就是一共就有三种情况

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=6e6+100;
int biaoji[maxn];
int cnt=0;
int prime[maxn];
void inint(){
    for(int i=2;i<=maxn;i++){
        if(!biaoji[i]){
            prime[++cnt]=i;    
        }
        for(int j=1;j<=cnt&&i*prime[j]<maxn;j++){
            biaoji[i*prime[j]]=1;
            if(i%prime[j]==0){
                break;
            }
        } 
    }
}
int main(){
    inint();
    int n;
    cin>>n;
    if(n==0||n==1){
        cout<<-1<<endl;
    }
    else{
        int sum=0;
        for(int i=1;i<=n;i++){
            sum+=i;
        }
        if(!biaoji[sum]){
            cout<<1<<endl<<sum<<endl;
            return 0;
        }
        for(int i=2;i<=n;i++){
            int p=sum-i;
            if(!biaoji[i]&&!biaoji[p]){
                cout<<2<<endl;
                cout<<i<<" "<<p<<endl; 
                return 0;
            }
        }
        int flag=0;
        for(int i=2;i<=n;i++){
            if(!biaoji[i]){
                for(int j=2;j<=n;j++){
                    int p1=i,p2=j,p3=sum-i-j;
                    if(!biaoji[p1]&&!biaoji[p2]&&!biaoji[p3]){
                        cout<<3<<endl;
                        cout<<i<<" "<<j<<" "<<p3<<endl;
                        flag=1; 
                        break;
                    }
                }
            }
            if(flag){
                break;
            }    
        } 
    }
} 
/*
2342
*/

作为老学长,我决定给每一个学弟学妹发一朵小红花以鼓励他们加紧训练。然而发一朵太掉价了,所以我决定发一堆,当前我共有nn堆花朵,第ii堆有a[i]a[i]朵花,0≤a[i]≤1e90≤a[i]≤1e9。然而本人具有强迫症,我想给每一堆花都增加xx朵,使得这nn堆花的gcd最大。

因为19的人数不多,所以n≤20n≤20,请帮我求出最大的gcd并求出满足最大gcd时最小的xx是多少。

Input

第一行一个nn,随后nn个数字代表nn堆花的数量

Output

请输出最大的gcd是多少,并求出满足最大gcd时最小的xx是多少。

Samples

Input 复制
2
7 10
Output
3 2

Source

2021年昆明区域赛选拔【数论】

 

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
int a[maxn];
int b[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    } 
    sort(a+1,a+n+1);
    if(a[1]==a[n]){
        cout<<a[1]<<0<<endl;
    }
    else{
        int x=0,p=0;
        for(int i=1;i<=n;i++){
            x=__gcd(x,a[i]);
        }
        for(int i=1;i<=1e4;i++){
            int z=0;
            for(int j=1;j<=n;j++){
                b[j]=a[j]+i;
                z=__gcd(z,b[j]);
            }
            if(z>x){
                x=z;
                p=i;
            }
        }
        cout<<x<<" "<<p<<endl;
    }
}

 

标签:联盟,阵容,战斗力,nn,数论,选拔,int,maxn,gcd
来源: https://www.cnblogs.com/lipu123/p/14489045.html