安徽省2015年“京胜杯”大学生程序设计竞赛First Blood

First Blood

1. 题目

Time Limit: 1000 MS

Memory Limit: 65536 KB

Total Submissions: 431 Accepted: 45

Description

盖伦是个小学一年级的学生,在一次数学课的时候,老师给他们出了一个难题:

老师给了一个正整数 n,需要在不大于n的范围内选择三个正整数(可以是相同的),使它们三个的最小公倍数尽可能的大。盖伦很想第一个解决这个问题,你能帮助盖伦拿到“first blood”吗?

Input

首先是一个正整数T,表示有T组测试数据

每组测试数据是一个正整数n(1<=n<=10^6)

Output

对于每组测试数据,输出最大的最小公倍数,每个输出单独占一行

Sample Input

2
9
7

Sample Output

504
210

Source

安徽省2015年“京胜杯”大学生程序设计竞赛


2. 算法描述

  1. 任意正整数v与v-1必定互质,v*(v-1)为两个数最小公倍数的最大值,v由最大范围n选起;
  2. 再选一数u,由于两数的最小公倍数与最大公约数之积等于两数之积,因此最小公倍数表示为(v*(v-1)*u)/gcd(v*(v-1),u),故在V选定的情况下最小公倍数的大小由u/gcd(v*(v-1),u)决定,因此u不能与v或v-1相同,u由v-2开始选取,直到v(v-1)*u<max_lcm为止(因为最小公倍数的最大值为三个数的乘积),记录这期间的最大的最小公倍数值max_lcm;
  3. v值减一,若max_lcm < v*(v-1)*(v-2),则u由v-2开始再进行一次第2步,完成后max_lcm 与 v*(v-1)*(v-2)比较,直到不满足“<”,输出max_lcm。

3. 注意事项

注意特殊值

  1. n=1时,v-1,v-2不存在,max_lcm=1;
  2. n=2时,v-2不存在,max_lcm=2;

4. 源代码

第一次提交:

//辗转相除法的版本
#include
#include

using namespace std;

long long gcdByDiv(long long a,long long b);

int T;
long long n,v,v_lcm,u,max_lcm,temp_lcm;

int main(void)
{
int t;
cin >> T;
for (t = 0; t < T; ++t)
{
cin >> n;
v=n;
max_lcm=0;
v_lcm=v(v-1);
while(v_lcm
(v-2) > max_lcm)
{
u=v-2;
while(v_lcm % u != 0)
{
temp_lcm = v_lcm * u / gcdByDiv(v_lcm,u);
if(temp_lcm > max_lcm) max_lcm = temp_lcm;
u--;
}
v--;
}
cout << max_lcm << endl;
}
return 0;
}

long long gcdByDiv(long long a,long long b)
{
long long c = a>b?a:b;
long long result = a>b?b:a;
long long temp=0;

c = c % result;
while(c!=0)
{
temp = c;
c = result;
result = temp;
c= c % result;
}
return result;
}
结果:
第一次提交结果

经过多次错误提交后改正了一些错误:
多次提交结果

最终通过源代码:

include

include

using namespace std;

long long gcdByDiv(long long a,long long b);

int T;
long long n,v,v_lcm,u,max_lcm,temp_lcm;

int main(void)
{
int t;
cin >> T;
for (t = 0; t < T; ++t)
{
cin >> n;
v=n;
max_lcm=0;

if(v-1>0)
{
v_lcm=v(v-1);
if(v-2>0)
u=v-2;
else
u=v-1;
}
else
{
v_lcm=v;
u=v;
}
while(v_lcm
u > max_lcm)
{
//while(v_lcm % u != 0)
while(v_lcmu > max_lcm)
{
temp_lcm = v_lcm * u / gcdByDiv(v_lcm,u);
if(temp_lcm > max_lcm) max_lcm = temp_lcm;
u--;
}
v--;
if(v-1>0)
{
v_lcm=v
(v-1);
if(v-2>0)
u=v-2;
else
u=v-1;
}
else
{
v_lcm=v;
u=v;
}
}
cout << max_lcm << endl;
}
return 0;
}

long long gcdByDiv(long long a,long long b)
{
long long c = a>b?a:b;
long long result = a>b?b:a;
long long temp=0;

c = c % result;
while(c!=0)
{
temp = c;
c = result;
result = temp;
c= c % result;
}
return result;
}

posted @ 2016-04-30 09:27  夕音  阅读(1108)  评论(0)    收藏  举报