Codeforces Round #708 (Div. 2) C1、C2 k-LCM


题意

给出两个数n,k,要求找到k个数,使k个数的最小公倍数 L C M ( a 1 , a 2 , a 3 , … … a k ) < = n 2 LCM (a_1,a_2,a_3,……a_k)<= {n \over 2} LCM(a1,a2,a3,ak)<=2n,easy题中k恒定为3。


一、C1. k-LCM (easy version)

因为两道题有一定的关联,是从k最小为3,逐渐推广k为任意数,我们可以试着从k=1开始观察有什么规律(这话我瞎编的,因为我实在是没法一眼看出来怎么做,从题解倒推可能可以这么看出来……大概下次可以这么试试……)


k = 1 k=1 k=1时, a 1 = n a_1=n a1=n,必不可能小于等于 n 2 n\over2 2n ,所以没啥参考价值(狗头)

k = 2 k=2 k=2时, a 1 , a 2 a_1,a_2 a1,a2找这俩的最小公倍数就好,而且保证它们小于等于 n 2 n\over2 2n。很容易(bushi)找到一对一定成立的解,当n为偶数的时候, a 1 = a 2 = n 2 a_1=a_2={n\over2} a1=a2=2n时, a 1 , a 2 a_1,a_2 a1,a2的最小公倍数就是它们本身,且满足小于等于 n 2 {n\over2} 2n。接着提出疑问,n为奇数的时候呢,感觉会多出一个1,那是不是可以在k=3的时候拿来凑数呢?

k = 3 k=3 k=3时,当n为奇数的时候,根据 k = 2 k=2 k=2时的推导,有一组解必定满足要求 ,即 ( n − 1 2 , n − 1 2 , 1 ) ({ n-1\over 2 },{n-1\over 2 },1) (2n1,2n1,1)。那么当k为偶数时,是否也会有一组一定满足条件的解呢?

当n为偶数时 a 1 , a 2 a_1,a_2 a1,a2都为 n − 1 2 {n-1\over2} 2n1时,剩下的 a 3 = 2 {a_3}=2 a3=2,此时当且仅当 n − 1 2 {n-1\over2} 2n1是2的倍数 L C M ( n − 1 2 , n − 1 2 , 2 ) LCM({n-1\over2},{n-1\over2},2) LCM(2n1,2n1,2)<= n 2 {n\over2} 2n,令 n − 1 2 = 2 ∗ k {n-1\over2}=2*k 2n1=2k,化简得n=4*k+2。 而又因为n为偶数 , 所以n不为4的倍数时, ( n − 1 2 , n − 1 2 , 2 ) ({n-1\over2},{n-1\over2},2) (2n1,2n1,2)为一组解。进一步分析,n为4时,如何找到一组一定满足条件的解。即n=4k时,可以直接讲n拆分为2k,k,k,则此时LCM(2k,k,k)=2k= n 2 {n\over2} 2n,满足条件。所以n为4的倍数时, ( n − 1 2 , n − 1 4 , n − 1 4 ) ({n-1\over2},{n-1\over4},{n-1\over4}) (2n1,4n1,4n1)为一组解

总结:

  • 当n为奇数时,答案为 ( n − 1 2 , n − 1 2 , 1 ) ({ n-1\over 2 },{n-1\over 2 },1) (2n1,2n1,1)
  • 当n为偶数且不为4的倍数时,答案为 ( n − 1 2 , n − 1 2 , 2 ) ({n-1\over2},{n-1\over2},2) (2n1,2n1,2)
  • 当n为偶数且为4的倍数时,答案为 ( n − 1 2 , n − 1 4 , n − 1 4 ) ({n-1\over2},{n-1\over4},{n-1\over4}) (2n1,4n1,4n1)

代码:

#include<iostream>
using namespace std;
int main()
{
	ios::sync_with_stdio(0);
	int t,n,k;//k一定为3 
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
	 	if(n&1)		//n为奇数 
	 		cout<<"1 "<<(n-1)/2<<" "<<(n-1)/2<<endl;
 		else if(n%4)//n为偶数且不为4的倍数
		 	cout<<"2 "<<(n-2)/2<<" "<<(n-2)/2<<endl;
	 	else 		//n为偶数且为4的倍数 
	 		cout<<n/2<<" "<<n/4<<" "<<n/4<<endl;
	}
	return 0;
}

二、C2. k-LCM (hard version)

对于C2,与C1的区别在于,k是大于等于3的不定值,但我们也许可以继续C1的思路,即对于n的各种情况,找到一组必定满足条件的解。(PS:k=3是k最小的情况,也许可以直接化成C1的题目)


接下来我们来讨论n的各种情况,首先我们可以试着将题目尽可能的往C1靠近,现在有k个数,如果我们只讨论最开始的三个数,其他的数全部用1代替,那么就相当于只需要求三个数,使其满足 a 1 + a 2 + a 3 = n − k + 3 a_1+a_2+a_3=n-k+3 a1+a2+a3=nk+3 L C M ( a 1 , a 2 , a 3 ) < = n 2 LCM(a_1,a_2,a_3)<={n\over2} LCM(a1,a2,a3)<=2n。由C1知 a 1 + a 2 + a 3 a_1+a_2+a_3 a1+a2+a3一定满足 L C M ( a 1 , a 2 , a 3 ) < = n − k + 3 2 LCM(a_1,a_2,a_3)<={n-k+3\over2} LCM(a1,a2,a3)<=2nk+3,自然也就一定满足条件。

#include<iostream>
using namespace std;
void f(int n)
{
	if(n&1)		//n为奇数 
		cout<<"1 "<<(n-1)/2<<" "<<(n-1)/2;
	else if(n%4)//n为偶数且不为4的倍数
		cout<<"2 "<<(n-2)/2<<" "<<(n-2)/2;
	else 		//n为偶数且为4的倍数 
		cout<<n/2<<" "<<n/4<<" "<<n/4;
}
int main()
{
	ios::sync_with_stdio(0);
	int t,n,k;//k一定为3 
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
	 	f(n-k+3);
	 	for(int i=1;i<=k-3;i++)
	 		cout<<" "<<1; 
 		cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值