4861(蓝桥). 坤坤的魔法游戏

 

问题描述

在一个神秘的世界里,坤坤正在玩一个古老的魔法游戏。这个游戏的目标是将一些神秘的咒语石头分组。每个咒语石头都有一个独特的编号,范围是从 2 到 𝑁。在每一步,坤坤可以选择两个独特的咒语石头,如果他们共享一个大于 1 的共同因子,就可以将它们归入同一组。坤坤会一直将石头进行分组,直到不能再进行分组为止。

在这个游戏中,归属于一个组的石头形成了等价关系。这意味着如果石头 𝑎 和石头 𝑏 在同一组,石头 𝑏 和石头 𝑐 也在同一组,那么石头 𝑎 和石头 𝑐 就被认为是在同一组。

/* 例如:a=2,b=6,c=3  a,b有共同因子2(a,b在同一组),b,c有共同因子3 (b,c在同一组),所以a,c视为在同一组,既a,b,c在同一组 */

坤坤的任务是找出最后形成的组的总数。

输入格式

第一行将包含一个整数 𝑇,表示测试案例的数量。然后是 𝑇 行输入,每行包含一个整数 𝑁。

数据范围保证:1≤𝑇≤2×1e5,1≤T≤2×1e5,2≤𝑁≤1e7,2≤N≤1e7。

 C++ 时间限制:2s,空间限制:256MB

输出格式

对于每个测试案例,输出一行,表示最后形成的组的总数。

样例输入

3
2
4
8

样例输出

1
2
3

说明

测试案例 1:最后的组是 { 2 }。

测试案例 2:最后的组是 { 2,4 } 和 { 3 }。

测试案例 3:最后的组是 { 2,3,4,6,8},{ 5 } 和 { 7 }。

思路分析:

        首先,所有的偶数都有共同因子2,最终一定能分到一组里,所以我们只需判断奇数部分最终能生成多少组。

        例子:N==10,既 {2,3,4,5,6,7,8,9,10},奇数{3,5,7,9}

        1.{2,4,6,8,10}  //所有偶数成为一组

        2. 第一个奇数3,与上面的组中的2和6形成了等价关系,所以3与它们分为一组既{2,3,4,6,8,10}

        3. 第二个奇数5,与上面的组中的2和10形成了等价关系,所以5与它们分为一组既{2,3,4,5,6,8,10}

        4.第三个奇数7,与上面的组中无法形成等价关系,所以7单独分为一组,既{2,3,4,5,6,8,10},{7}  (思考,N至少等于多少的时候,7才会出现等价关系?没错,当2x7=14,既N==14开始,7才有等价关系)

        5.第四个奇数9,与上面的组中的3,6有共同因子3,能形成等价关系,所以最终形成的组为{2,3,4,5,6,8,9,10},{7},共两组

我们发现4个奇数中,前两个都能与偶数组中的某个偶数形成等价关系,从而进入偶数组里面,而第三个奇数7,却需要N至少等于14开始,既与2和14形成等价关系,才能进入偶数组里面。但第四个奇数9却能与前面出现过的数有共同因子(3和6),却不用N至少等于18开始这个条件。

仔细观察,我们发现,3、5、7其实都是素数,一个素数如果要找到跟它有共同因子的数,我们只能从这个素数后面开始找(往前找是找不到一个数跟它有共同因子的(1不算)),而离这个素数最近的根它有共同因子的数就是2x这个素数,例如2x7=14。    而不是素数的9,一定与9前面的某一个数有共同因子,所以9可以进入前面已形成的组里。

加深理解:N==100;

最终形成的组为{2,3,4,5,6,7......49,50,51,52,54,55,...99,100}  {53} {59} {61} {67} {71} {73} {79} {83} {89} {97}

在2~100中,2~50内的数乘以2后都能在4~100内中找到, 50后面的数除了素数以外都能与前面有共同因子,而50后面的数中的素数由于没有共同因子,所以各自成为一组。

总结:
因为:

在2~N中,2~(N/2)的数乘以2其实都能在4~N都找到,而N/2~N除了素数以外的数,都能与前面的某一个数有共同因子,所以它们将组成一个组(因为等价关系) 。

所以:

2~N/2与N/2~N的非素数将成为一组     N/2~N中的素数各自成为一组  

坤坤的任务:是找出最后形成的组的总数(sum)。  

关键就是求N/2~N之间到底有多少个素数?

关键代码:

#include <iostream>
using namespace std;
const int MAX=10000001; 
int fac[MAX]={0},a[MAX]={0},num=0;   //num记录有多少个素数

void ai(){    //埃式筛法
  for(int i=2;i<MAX;++i){
  if(fac[i]==0)
    for(int j=i;j<MAX;j+=i)
    fac[j]=i;
  if(fac[i]==i) ++num;    //如果(fac[i]==i),则说明i是素数,更新num
  a[i]=num;  //a[i]存储从2到i之间有多少个素数
  }       //a[2]=1,a[3]=2,a[4]=2,a[5]=3,a[6]=3,a[7]=4
}

// a[6]-a[3]=3-2=1,代表着:2到6之间的素数(2,3,5)-2到3之间的素数(2,3)=3到6之间的素数(5)

int main()
{
  ai();    //初始化
  int T,N,sum;  //sum为总组数
  cin>>T;
  while(T--){    //T组测试用例
    cin>>N;
    sum=1;   //2~N/2的数和N/2~N的非素数为一组
    //if(N/2<2) --sum;  N==2||N==3的情况sum会多算一次 ,虽然测试用例没有
    sum+=a[N]-a[N/2];    //前缀和
    cout<<sum<<endl;
    }
  return 0;
}

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 蓝桥测试数据大小为60.06 MB。数据的大小通常是指数据占用的存储空间大小。在计算机中,数据以二进制的形式存储,每个二进制位(位)可以表示一个0或1,8个二进制位组成一个字节(Byte)。因此,60.06 MB表示数据占用了60.06兆字节的存储空间。 蓝桥测试数据大小为60.06 MB,换算成比特(Bits)为480.48兆比特(Mb)。MB(兆字节)和Mb(兆比特)之间的转换关系是:1兆字节(MB)= 8兆比特(Mb)。所以,60.06 MB乘以8得到480.48 Mb。 可以根据数据的大小来估计需要的存储空间和传输时间。传输时间取决于网络速度和文件大小。网络速度通常以比特每秒(bps)或兆比特每秒(Mbps)为单位。如果网络速度是1 Mbps,将60.06 MB转换成比特(Bits),并除以1 Mbps,可以得到传输该数据所需的时间。根据计算,以1 Mbps的传输速度传输60.06 MB的数据需要约480.48秒。 综上所述,蓝桥测试数据大小为60.06 MB,换算成比特为480.48 Mb。传输该数据所需的时间取决于网络速度,根据1 Mbps的传输速度估计,大约需要480.48秒。 ### 回答2: 蓝桥测试数据的大小为60.06MB。MB是存储容量的单位,表示兆字节。60.06MB大约相当于60060000字节。这个大小可以用来评估蓝桥测试数据的存储需求。根据文件类型和内容的不同,60.06MB可以容纳不同数量和大小的文件。例如,对于文本文件而言,这个大小可以容纳非常大的文本文件,大约相当于60000页的纸质文档。对于音频文件或视频文件而言,这个大小可能只能容纳数分钟的内容,具体取决于文件的编码和比特率。总的来说,60.06MB的大小在当前计算机及存储技术下不算特别大,但也不小。根据具体的使用场景和需要,我们可以相应地调整存储设备的容量,以便满足对蓝桥测试数据的存储和传输需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值