题意:
对于 a, b, c, 以及它们的最小公倍数 L, 给定 a,b,L 求 最小的 c
思路:
我们知道 L = lcm( lcm(a,b), c );
我们首先求得 a b 的 lcm1,然后根据 lcm1 和 L 的关系求 c ,
手推一下会发现:c 存在的条件是 L 是 lcm1 的倍数;
然后就是求 c ,我们可以理解为,t = L / lcm1 这一部分是 c 提供的,要想 c 最小,除了这些,c的其他的部分应该是 c 和 lcm1 的 gcd,而且还要使他们的gcd 最小
要使 t 这一部分起作用的话,c 的其他部分(他们的gcd)就要恰好包含所有 lcm1 中所有的 t 的质因子。。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1000 + 7, maxd = 400000015, mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
ll a, b, L;
int cnt = 0;
bool p[maxn];
int prim[maxn];
void init() {
memset(p, 1, sizeof p);
for(int i = 2; i <= maxn; i += 2) p[i] = 0;
prim[cnt++] = 2;
for(int i = 3; i <= maxn; i += 2) {
if(p[i]) prim[cnt++] = i;
for(int j = 0; prim[j]*i <= maxn && j < cnt; ++j) {
p[prim[j]*i] = 0;
}
}
//for(int i = 0; i < 100; ++i)
// cout << prim[i] << " ";
}
ll gcd(ll a, ll b) {
return b == 0 ? (a) : (gcd(b, a%b));
}
int main() {
init();
int T;
scanf("%d", &T);
for(int t_ = 1; t_ <= T; ++t_) {
scanf("%lld %lld %lld", &a, &b, &L);
ll lcm1 = a * b / gcd(a, b);
if(L % lcm1 != 0) {
printf("Case %d: impossible\n", t_);
}
else {
ll t = L / lcm1;
ll ans = t;
if(t > 1) {
for(int i = 0; i < cnt; ++i) {
if(t % prim[i] == 0) {
while(t % prim[i] == 0) t /= prim[i];
while(lcm1 % prim[i] == 0) {
ans *= prim[i];
lcm1 /= prim[i];
}
}
if(t <= 1) break;
}
}
printf("Case %d: %lld\n", t_, ans);
}
}
return 0;
}