洛谷传送门:CF1712B Woeful Permutation - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
难度:普及-
知识点:
数论(排序不等式,gcd(Greatest Common Divisor),lcm(Least Common Multiple))
思路:
前提,上面这个公式要知道。
①如何让gcd尽可能小?此时又有一个结论:相邻的两个正整数一定互质。
所以,最终的数列,每个数pi与自己的下标i,pi与i是相邻的
相邻可以有很多种,比如51234,23451,21435,13254都是相邻的,我们再看②
②如何让a*b尽可能大?此时又有一个结论:排序不等式_百度百科 (baidu.com)
所以,我们选择13254,而不是21435以及其他的
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int q,n; scanf("%d", &q);
int odd[100005];//n为奇数时
int even[100005];//n为偶数时
odd[0] = 1;
for(int i = 1; i<100001; i=i+2){//13254
odd[i] = i+2;
odd[i+1] = i+1;
}
for(int i = 0; i<100001; i=i+2){//214365
even[i] = i+2;
even[i+1] = i+1;
}
while(q--){
scanf("%d", &n);
if(n%2){ //奇数
for(int i = 0; i<n; i++) printf("%d ", odd[i]);
}
else for(int i = 0; i<n; i++) printf("%d ", even[i]);
printf("\n");
}
return 0;
}
/*
知识点:数论(排序不等式)
心路历程:
顺序的话,答案就是每个数求和
首先猜测倒序可能可以得到最大答案
用3来假设
321 -> 3 + 2 + 1 = 6;
132 -> 1 + 6 + 6 = 13;
第一次假设是错误的
继续枚举看看能不能发现什么
213 -> 2 + 2 + 3
231 -> 2 + 6 + 3
312 -> 3 + 2 + 6
第二次假设:1是1;后面的倒序
用4来假设
1432 -> 1 + 4 + 3 + 4 = 12
还不如13大,第二次假设错误
思考:两个数如果有一个是另一个的因数,那就浪费了
为了不浪费,错位就一定不是另一个数的因数
这样最小公倍数就是两个数的乘积
当几个数的和相同时,2143 比 4321 大
2143: 2 + 2 + 12 + 12 = 28
4321: 4 + 6 + 6 + 4 = 20
所以第三次假设:先顺序排列,右边开始两两互换
再枚举多几个看看:
4123: 4 + 2 + 6 + 12
这次假设应该没问题,提交,ac!
看题解之后,思路没错,优化了一下代码
*/
推荐博文:CF1712B 题解 - YYHDoggy 的博客 - 洛谷博客 (luogu.com.cn)