安徽省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. 算法描述
- 任意正整数v与v-1必定互质,v*(v-1)为两个数最小公倍数的最大值,v由最大范围n选起;
- 再选一数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;
- v值减一,若max_lcm < v*(v-1)*(v-2),则u由v-2开始再进行一次第2步,完成后max_lcm 与 v*(v-1)*(v-2)比较,直到不满足“<”,输出max_lcm。
3. 注意事项
注意特殊值
- n=1时,v-1,v-2不存在,max_lcm=1;
- n=2时,v-2不存在,max_lcm=2;
4. 源代码
第一次提交:
//辗转相除法的版本
#include <iostream>
#include <algorithm>
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 <iostream>
#include <algorithm>
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_lcm*u > 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;
}

浙公网安备 33010602011771号