2011 第二届蓝桥杯总决赛- 第三题 求1-n 的最小公倍数(n小于101)

 一、我们先考虑 当n< 41时, 结果是可以用long long 保存的。

       【1-7】的各个数因式分解是:2,3,2*2,5,2*3,7,2*2*2;最小公倍数:2*3*2   *5*    7* 2

1、设【1~n-1】的最小公倍数为a[n-1],如果 a[n-1]%n=0;那么a[n]=a[n-1];例如[1~5] 和[1~6];

2、否则,n这个数一定含有 必须乘到 a[n-1]上 的素因子,eg:8;

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define maxn 15
int prime[maxn] = {2,3,5,7,11,13,17,19,23,29, 31,37,41,43};
int main()
{
    int n,i,j,t,k;
    long long sum[42],temp;
    sum[1]=1;sum[2]=2;
        for(k=2; k<=40; k++)
        {
            if(sum[k-1]%k)//含有多的质因子
            {   temp=sum[k-1];
                for(i=0; prime[i]<=k; i++)
                  if(k%prime[i]==0)
                  {temp=temp*prime[i];}
               sum[k]=temp;
            }
            else
            sum[k]=sum[k-1];
        }
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
       printf("%lld\n",sum[n]-1);
    }
    return 0;
}

二、考虑到1-100的最小公倍数肯定超出__int64.所以需要转化成字符串问题来解

仔细观察会发现,【1-n】的最小公倍数,是【1-n-1】的最小公倍数乘以n的所有素因子中没有被【1-n-1】包含的素因子。
例如:【1-7】的最小公倍数是2*3*2*5*7,8=2*2*2,(8中2出现3次,【1-7】的素因子中只出现2次)那么【1-8】就是2*3*2*5*7*2

思路:(1)先求出1——>n 的因子;

           (2)然后只要做一个大数乘法即可。

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
#define M 101
int factor[101];//存所有的因子;
struct  a{
  int c[43];//经输出测试,最长只有42
  int length;
  a()//构造函数
  {
     length=0;
  }
}ans[101];
void getfactor()
{
   int i,j;
   for(i=1;i<M;i++)
   {
      factor[i]=i;
      for(j=2;j<i;j++)
         if(factor[i]%factor[j]==0)
          factor[i]/=factor[j];
   }
}
void bigmulti()//高精度乘法
{
   int f=0,i,j,b;
   ans[1].c[0]=1;
   ans[1].length=1;
   for(i=2;i<=100;i++)
   {
      b=factor[i];
      for(f=0,j=0;j<ans[i-1].length;j++)
      {
         f=ans[i-1].c[j]*b+f;
         ans[i].c[j]=f%10;
         f/=10;
      }
      while(f)
      {
         ans[i].c[j]=f%10;
         f/=10;
         j++;
      }
      ans[i].length=j;
   }
}
void print(int i)//输出[1,n]的最小公倍数 ans[n]
{
   for(int j=ans[i].length-1;j>=0;j--)
      printf("%d",ans[i].c[j]);
   printf("\n");
}
int main()
{
    //freopen("ans.txt","w",stdout);
    getfactor();
    bigmulti();
    int n;
    while(cin>>n)
       print(n);
    return 0;
}

问题拓展:

1.判断1到n连续n个数的最小公倍数与1到n-1连续n-1个数的最小公倍数是否相等

思路:判断n是不是素数? (1)如果不是素数,找到一个i<=sqrt(n)的约数,判断  gcd((n/i),i)==1,那么输出YES;(2)否则,是素数,那么结果是NO。

代码:

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
#define LL long long
LL gcd( LL a,LL b)
{
 return b==0?a:gcd(b,a%b);
}
int main()
{
    LL n;
    scanf("%I64d",&n);
    int flag=1;
    for(LL i=2; i*i<=n; i++)
       if(n%i==0)
        {
            LL tt=gcd((n/i),i);
            if(tt-1==0)
            {
                flag=0;
                printf("YES\n");
                break;
            }
        }
    if(flag) printf("NO\n");

   return 0;
}

2、hdu 2028  n个数的最小公倍数

思路:先求两个数的最大公约数,再求最小公倍数。

#include <cstdio>
#include <iostream>
using namespace std;
int Gcd(int  a,int b)
{
    return b==0?a:Gcd(b,a%b);
}
int main()
{
	int n;
	int ans,yueshu,temp;
	while(cin>>n)
	{
	  ans=1;
	  for(int i=0;i<n;i++)
	  {
	    scanf("%d",&temp);
	    yueshu=Gcd(ans,temp);
		ans=temp/yueshu*ans;//先除再乘,以防溢出
	  }
	  printf("%d\n",ans);
	}
   return 0;
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据给出的试来源,第十四届蓝桥杯大赛软件赛决赛,我们可以看到一系列字母和数字的组合。根据目中的标识,我们可以做如下解释: pc-6:这可能表示参赛者的类别或背景,其中四个字母“pc”可能是某个组织或机构的缩写,后面的数字“6”可能是该组织或机构的编号或类别。 jc-6:同样地,这个组合可能是另一个参赛者的类别或背景,其中四个字母“jc”可能代表另一个组织或机构的缩写,后面的数字“6”可能是其编号或类别。 ja-4:这个组合代表第三个参赛者的类别或背景,其中四个字母“ja”可能表示另一个组织或机构的缩写,后面的数字“4”可能是其编号或类别。 jg-4:最后一个组合也代表一个参赛者的类别或背景,其中四个字母“jg”可能代表另一个组织或机构的缩写,后面的数字“4”可能是其编号或类别。 由于缺乏更多的背景信息,我们无法给出具体的解释。但可以推测这些字母和数字组合可能是用来标识参加蓝桥杯大赛软件赛决赛的不同参赛者,每个组合可能代表一个不同的参赛组织或机构,并有着各自的编号或分类。这种标识方法是为了方便组织者和参赛者进行管理和识别。 在蓝桥杯大赛软件赛决赛中,不同的参赛者将展示出他们的软件开发技能和能力,通过一系列的比赛环节,最终决出最优秀的软件开发团队或个人。这场比赛旨在鼓励和推动年轻人对软件开发的兴趣和热情,培养他们的创新思维和解决问的能力,同时也为软件行业的发展和人才的选拔做出贡献。 总之,根据提供的信息,我们可以推测这些字符和数字组合可能是用来标识蓝桥杯大赛软件赛决赛的不同参赛者,同时也给出了关于大赛的一些背景和目的。这样的组合可以方便参赛者的管理和识别,同时也让人们更加了解这场竞赛的性质和意义。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值