2015编程之美初赛第三题质数相关

1、解题思路

按题要求,输入数据后先进行是否有两两相同的数据的判断,接着进行从小到大的排序,由于是求质数无关,则集合中任何一对数都不能质数相关,本人采用顺序遍历,将集合中每个数字分为必须包含和必须排外两种情况遍历,首先集合第一个数必须包含,且作为子集中第一个元素,由于是有序数据,只需从集合第二个数遍历起,对加人子集的每个数做质数相关判断(需要遍历一遍),若与子集每个数都质数无关,则将该数纳入该子集,直到遍历完集合后续所有数据,完了统计子集大小;再来第二遍遍历,这是最外循环从大集合第二个数据起,此时已排出第一个数据,第二个数据作为子集的第一元素,后续遍历跟前面一样,完了统计子集大小,可以设一个变量存储最大子集,只要比原来子集大就更新;直到集合最后一个遍历完,此时可以得到最大子集了。

例如:集合A={2,4,8,16,32},第一遍,2作为子集第一个元素,4/2=2是质数,排除,8/2=4非质数,纳入子集,此时子集={2,8},接着16/8=2,排除,接着32/8=4,32/2=16,纳入子集,子集={2,8,32},此时子集大小为3,第二遍,4作为子集第一个元素,8/4=2排除。16/4=4 ,16纳入,32/16=2,32排除,子集={4,16},第三遍,8作为子集第一个元素,16/8=2排除,32/8=4纳入,子集={8,32},第四遍,16作为子集第一个,32/16=2排除,子集={16},第五遍,32是自己第一个元素也是唯一的;得出子集汇中最大就是3;

下面是C++源代码:

#include<iostream>
using namespace std;
#include<algorithm>
//判断是否有相同的数
bool isSame(long *ps,int N)
{
    int i,j;
    for(i=0;i<N;i++)
        for(j=0;j<N;j++)
        {
            if(*(ps+i)==*(ps+j)&&i!=j)
                return false;
        }
    return true;
}
//判断是否是素数
bool isPrime(long n)
{
    int i;
    if(n<2)
        return false;
    else
    {
        for(i=2;i<=n/2;i++)
            if(n%i==0)
            {  

                return false;
            }
    }
        return true;
}  

int main()
{
    int T,N,maxSub;
    cin>>T;
    for(int i=0;i<T;i++)
    {
        cin>>N;
        long *ps = new long[N];
        long *subps=new long[N];
        maxSub=0;
        for(int j=0;j<N;j++)
            {
                cin>>*(ps+j);  

            }
        if(!isSame(ps,N))
                {
                    cout<<"有两两相同的数!"<<endl;
                }
        sort(ps,ps+N);  

        maxSub=0;
        for(int i=0;i<N;i++)
        {
            int cnt=1;
            for(int j=i;j<N;j++)
            {
                bool flag=true;
                *(subps+0)=*(ps+i);
                for(int k=cnt-1;k>=0;k--)
                {
                    if(*(ps+j)%*(subps+k)==0 && isPrime((*(ps+j))/(*(subps+k))))
                    {
                        flag=false;  

                        break;
                    }
                }
                if(flag==true)
                {  

                    *(subps+cnt)=*(ps+j);
                    cout<<"*(ps+j)"<<*(ps+j)<<endl;
                    cnt++;
                }
            }
            if(maxSub<cnt)
                maxSub=cnt;
        }
        printf("Case #%d: %d\n",i+1,maxSub-1);
    }
    return 0;
}  

原题目:

题三:质数相关

时间限制:2000ms

单点时限:1000ms

内存限制:256MB

描述

两个数a和 b (a

时间: 2024-10-28 07:40:43

2015编程之美初赛第三题质数相关的相关文章

2015编程之美初赛第一场 C 质数相关

 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数.一个集合S被称为质数相关,是指S中存在两个质数相关的数,否则称S为质数无关.如{2, 8, 17}质数无关,但{2, 8, 16}, {3, 6}质数相关.现在给定一个集合S,问S的所有质数无关子集中,最大的子集的大小. 输入 第一行为一个数T,为数据组数.之后每组数据包含两行. 第一行为N,为集合S的大小.第二行为N个整数,表示集

2015编程之美初赛第一场 B 建造金字塔

 时间限制:4000ms 单点时限:2000ms 内存限制:256MB 描述 在二次元中,金字塔是一个底边在x轴上的等腰直角三角形. 你是二次元世界的一个建筑承包商.现在有N个建造订单,每个订单有一个收益w,即建造此金字塔可获得w的收益.对每个订单可以选择建造或不建造. 建造一个金字塔的成本是金字塔的面积,如果两个或多个金字塔有重叠面积,则建造这些金字塔时重叠部份仅需建造一次. 建造一组金字塔的总利润是收益总和扣除成本.现给出这些订单,请求出最大利润. 输入 输入数据第一行为一个整数T,表示

2015编程之美初赛第一场 A 彩色的树

时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵n个节点的树,节点编号为1, 2, -, n.树中有n - 1条边,任意两个节点间恰好有一条路径.这是一棵彩色的树,每个节点恰好可以染一种颜色.初始时,所有节点的颜色都为0.现在需要实现两种操作: 1. 改变节点x的颜色为y: 2. 询问整棵树被划分成了多少棵颜色相同的子树.即每棵子树内的节点颜色都相同,而相邻子树的颜色不同. 输入 第一行一个整数T,表示数据组数,以下是T组数据. 每组数据第一行是n,表示树的节

2015编程之美初赛第二场扑克牌

一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52张牌中的若干张,请计算将它们排成一列,相邻的牌面值不同的方案数. 牌的表示方法为XY,其中X为面值,为2.3.4.5.6.7.8.9.T.J.Q.K.A中的一个.Y为花色,为S.H.D.C中的一个.如2S.2H.TD等. 输入 第一行为一个整数T,为数据组数. 之后每组数据占一行.这一行首先包含一个整数N,表示给定的牌的张数,接下来N个由空格分隔的字符串,每个字符串长度为2,表示一张牌.每组数

2014-04-19编程之美初赛题目及答案解析

第一题: 描写叙述 一般来说,我们採用针孔相机模型,也就是觉得它用到的是小孔成像原理. 在相机坐标系下,一般来说,我们用到的单位长度,不是"米"这种国际单位,而是相邻像素的长度.而焦距在相机坐标系中的大小,是在图像处理领域的一个很重要的物理量. 如果我们已经依据相机參数,得到镜头的物理焦距大小(focal length),和相机胶片的宽度(CCD width),以及照片的横向分辨率(image width),则详细计算公式为: Focal length in pixels = (ima

编程之美初赛第二场 集合

题目3 : 集合 时间限制:12000ms 单点时限:6000ms 内存限制:256MB 描述 统计满足下列条件的集合对(A, B)的数量: A,B都是{1, 2, -, N}的子集: A,B没有公共的元素: f(A)<= f(B).f(S)定义为S中所有元素的按位异或和.例如, f({}) = 0, f({1, 3}) = 2. 因为答案可能很大,你只需要求出它除以M的余数. 输入 第一行一个整数T (1 ≤ T ≤ 10),表示数据组数. 接下来是T组输入数据,测试数据之间没有空行. 每组数

微软2014编程之美初赛第一场——题目2 : 树

[来源] 题目2 : 树 [分析] 依据输入情况建立起树的模型.树的表示是一个表明父亲节点的数组.核心算法有两个: 计算某一节点的深度.用循环实现,一直向上找父亲节点,直到找到根节点.计算循环的次数即为深度. 计算某一节点的全部子节点.用递归实现. 本题在实现上节点的命名从0至N-1,与题目描写叙述不同. [代码] #include <iostream> #include <vector> using namespace std; vector<int> childre

2015编程之美复赛

第一题,不道是什么鬼.. 第二题猜数字. 很多用主席树,我不会,啊啊啊~~~~记得这题有出过吧,想了一发线段树的,把所有的数排序,同时把询问K排序, 做两发遍历,首先从小到大遍历所有的数,单点更新比K小的线段树的点,维护最大值,遇到>=K时则查询一发. 再从大到小遍历,更新比k大的,维护最小值,遇<=K时就查询.比较即可. #include <iostream> #include <cstdio> #include <cstring> #include &l

微软2014编程之美初赛第一场——题目3 : 活动中心

[来源] 题目3 : 活动中心 [分析] 本题採用的是三分法. 输入的一组点中找出左右边界.作为起始边界. while(右边界-左边界<精度){ 将左右边界构成的线段均匀分成3段,推断切割点的距离关系,抹去距离大的一段.更新左右边界. } 输出左(右)边界 [代码] #include <iostream> #include <vector> #include <cmath> #include <iomanip> using namespace std;