这题可以等同于找三个互质的数xyz(可以假设x<=y<=c),x+y+z=n/k,xyz都不能为1,然后w=n/k,如果w是偶数,那x=2,yz拆成两个相邻奇数(如果(w-2)%2是奇数就拆成相差4的奇数),如果w是奇数,那x=3,其他两数yz和偶数同样处理,如果得到的z和y是3的倍数,就y-2,z+2
最后得到的xyz如果有数等于1或者n%k不等于1都无解
链接:https://ac.nowcoder.com/acm/contest/6871/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
Special Judge, 64bit IO Format: %lld
Compute 对于某些特殊的数字有着独特的爱好。
例如,有三个正整数 a, b, c 和某一个目标值 k,如果 gcd(a,b)=gcd(b,c)=gcd(a,c)=k\gcd(a,b)=\gcd(b,c)=\gcd(a,c)=kgcd(a,b)=gcd(b,c)=gcd(a,c)=k,并且 a,b,c≠ka,b,c \neq ka,b,c=k ,那么他认为这三个数是一组好数。 其中gcd(x,y)\gcd(x,y)gcd(x,y)表示整数 x 和 y 的最大公约数。
当然这不够刺激。现在 Compute 想要知道,如果已知三个数的和 n 和目标值 k,是否存在一组 a, b, c 可以让它们是一组好数。
第一行输入一个整数 T (1≤T≤10001\leq T \leq 10001≤T≤1000),表示数据的组数。对于每组数据: 仅一行包含两个整数 n, k (1≤n,k≤10181\leq n,k \leq 10^{18}1≤n,k≤1018),分别表示 a, b, c 的和与目标值。
对于每一组数据,在一行输出三个整数,中间以空格分隔,表示找到的一种方案。 如果有多种方案,任意输出其中一种即可。 特别地,如果没有满足条件的方案,在一行输出 -1 -1 -1。
示例1
复制2 20 2 12 2
2 20 2 12 2
复制4 6 10 -1 -1 -1
4 6 10 -1 -1 -1
#include
#include
#include
using namespace std;
#define ll long long
#define mod 998244353
#define maxn 10500
#include
typedef std::mt19937 Random_mt19937;
Random_mt19937 rnd(time(0));
ll rd(ll l,ll r)
{
return (rnd()%(r-l+1)+l);
}
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll n,k;
scanf("%lld %lld",&n,&k);
//printf("t=%lld n=%lld k=%lld\n",t,n,k);
if(n%k!=0)
{
printf("-1 -1 -1\n");
}
else
{
ll x,y,z,w=n/k;
if(w%2==0)
{
x=2ll;
if(((w-x)/2ll)%2ll==1ll)
{
y=(w-x)/2ll-2ll;
z=(w-x)/2ll+2ll;
}
else
{
y=(w-x)/2ll-1;
z=(w-x)/2ll+1;
}
if(y<=2)
{
printf("-1 -1 -1\n");
}
else printf("%lld %lld %lld\n",x*k,y*k,z*k);
}
else
{
if(1)
{
x=3ll;
if(((w-x)/2ll)%2ll==1ll)
{
y=(w-x)/2ll-2ll;
z=(w-x)/2ll+2ll;
}
else
{
y=(w-x)/2ll-1;
z=(w-x)/2ll+1;
}
while(y%3==0||z%3==0) y-=2,z+=2;
}
if(y<=2||x<=2)
{
printf("-1 -1 -1\n");
}
else printf("%lld %lld %lld\n",x*k,y*k,z*k);
}
}
}
}