Atcoder Grand Contest 022 B
B题
题意
需要输出一个序列满足以下三个条件
* 序列中仅包含不相同的小于30000的数字
* 序列中一定存在两个互质元素(最大公因数为1)
* 序列中任何一个数A,与其余数的和B(sum(除去A之外的所有元素))一定不互质(最大公因数大于1)
笺释
当n为3时直接输出题目所给的2,5,63即可。
当n大于3时需要这样构造数列
for(int x=3;x+6<MAXM&&n>=4;x+=12,n-=2)
{
printf("%d %d ",x,x+6);
}
int x=2;
for(;n>=3;x+=6,n-=3)
{
printf("%d %d %d ",x,x+2,x+4);
}
if(n==1)
{
printf("%d ",x+4);
}
else if(n==2)
{
printf("%d %d ",x,x+2);
}
当n大于等于5的奇数时,就一定会至少进入一次循环1和一次循环2,就一定会产生2个以上的6,在最终的集合中,不管拆走哪一项,剩下数字组成的和式中一定存在着至少一个6,也就是说和式一定可以表示成整数X+6的形式,也就一定能提供2或者3作为公因子
边界分为这么几种情况
* n在使用3 6 9 12…30000用完之前就达到了3,那么输出2 4 6结束
* n在使用完3 6 9之后,保留任意整数2k+1的形式,那么每次对其减3最终有可能等于3(输出一组x x+2 x+4)或者等于1,等于1的话,输出一个能提供6的数字(x+4)(至于为何x+4一定能提供一个6,归纳一下就很显然)
当n为大于等于4的偶数时,同样分两种情况
* 一种是在没用完之前n达到2,则输出x(2)和x+2(4),同样能够提供两个以上的6。**
* 用完之后,保留任意偶数2k的形式,每次对其减3,假设减了z次,结果为2k-3z,【(2k-3z)/2】=【k-(3z)/2】,因此z为偶数时所得结果为偶数,即2,z为奇数时所得奇数,即1。但不论是哪种情况,边界输出的结果也总能提供一个6。
而循环1至少输出一个3与循环2至少输出一个2则保证了条件2恒成立(2和3互质)