蓝桥杯基础知识2 全排列 next_permutation(), prev_permutation()
#include<bits/stdc++.h>
using namespace std;
int a[10];
int main(){
for(int i = 1; i <= 4; ++i)a[i] = i; //4*3*2*1 = 24
bool tag = true;
while(tag){
for(int i=1; i <= 4; ++i)cout << a[i] << ' ';
cout << '\n';
tag = next_permutation(a + 1, a + 1 + 4);
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[10];
int main(){
a[1] = 2, a[2] = 3, a[3] = 4, a[4] = 1; //初始顺序为2341
bool tag = true;
while(tag){
for(int i=1; i <= 4; ++i)cout << a[i] << ' ';
cout << '\n';
tag = next_permutation(a + 1, a + 1 + 4);
}
for(int i = 1; i <= 4; ++i)cout << a[i] << ' ';
//从2开始进行全排列,输出最后一个排列4321后,顺序变为1234
return 0;
}
next_permutation函数用于生成当前序列的下一个序列。按字典序对序列重新排列,如果存在下一个排序,则当前序列更改为下一个排序,并返回true;如果当前序列已经是最后一个排列,则将序列更改为第一个排列,并返回false。
next_permutation全排列函数的时间复杂度是O(n),其中n是序列的长度。next_permutation()需要遍历和比较序列的每一个元素,以确定下一个排列组合。
#include<bits/stdc++.h>
using namespace std;
int a[10];
int main(){
a[1] = 2, a[2] = 3, a[3] = 4, a[4] = 1; //初始顺序为2341
bool tag = true;
while(tag){
for(int i=1; i <= 4; ++i)cout << a[i] << ' ';
cout << '\n';
tag = prev_permutation(a + 1, a + 1 + 4);
}
for(int i = 1; i <= 4; ++i)cout << a[i] << ' ';
//从2开始进行全排列,输出最后一个排列1234后,顺序变为4321
return 0;
}
prev_permutation函数用于生成当前序列的上一个序列。按字典序对序列重新排列,如果存在上一个排序,则当前序列更改为上一个排序,并返回true;如果当前序列已经是第一个一个排列,则将序列更改为最后一个排列,并返回false。
prev_permutation函数时间复杂度为O(n),其中n是序列的长度。prev_permutation()需要遍历和比较序列的每一个元素,以确定上一个排列组合。
208 蓝桥杯 带分数 简单
// C风格解法1,通过率100%,
//1-9枚举全排列,然后枚举 + 和 / 的位置,计算这个表达式是否等于N
// 100 = 3 + 69258 / 714
// 100 = 82 + 3546 / 197
//123456789
//.........
//987654321
#include <bits/stdc++.h>
int a[10]; // 用来枚举全排列
int f(int l, int r){ // 定义函数f,获取数字“a[l]a[l + 1]...a[r]”
int ret = 0;
// 345
// ret = 3
// ret = 3 * 10 + 4 = 34
// ret = 34 * 10 + 5 = 345
for(int i = l; i <= r; i++)ret = ret * 10 + a[i];
// 正数组转整型
return ret;
}
int main(){
int N; std::cin >> N ; // 读入 N
int ans = 0; // 记录有多少种方式
for(int i = 1; i <= 9; i++)a[i] = i;
// 给全排列数组a赋值, a[1] = 1 a[2] = 2,...,a[9] = 9
do{
for(int i = 1; i <= 9; i++){ // 枚举 + 的位置
for(int j = i + 1; j < 9; j++){ // 枚举 / 的位置
if(f(i + 1, j) % f(j + 1, 9) != 0){continue;} // B / C != 0, % 为取模运算
// continue 跳过当前循环 break 结束当前最内层的整个循环
int g = f(1, i) + f(i + 1, j) / f(j + 1, 9); // A + B / C == N
if(g == N)ans++;
}
}
}while(std::next_permutation(a + 1, a + 9 + 1));
// 枚举a的所有排列,打乱a数组中1-9的位置
std::cout << ans <<'\n';
return 0;
}
//C++风格解法2,通过率100%
// 1-9枚举全排列,然后枚举 + 和 / 的位置,计算这个表达式是否等于N
// 100 = 3 + 69258 / 714
// 100 = 82 + 3546 / 197
//123456789
//.........
//987654321
#include <bits/stdc++.h>
int main(){
int N; std::cin >> N ; // 读入 N
int ans = 0; // 记录有多少种方式
std::array<int, 9> a{}; // C++数组,与int a[9]等价
auto f = [&](const int &l, const int &r){
// 给全排列数组a赋值, a[1] = 1 a[2] = 2,...,a[9] = 9
int ret = 0;
for(int i = l; i <= r; i++)ret = ret * 10 + a[i];
return ret; // 正数组转整型
};
for(int i = 0; i < 9; i++)a[i] = i + 1;
do{
for(int i = 0; i <= 8; i++){ // 枚举 + 的位置
for(int j = i + 1; j < 8; j++){ // 枚举 / 的位置
if(f(i + 1, j) % f(j + 1, 8) != 0){continue;} // B / C != 0, % 为取模运算
// continue 跳过当前循环 break 结束当前最内层的整个循环
int g = f(0, i) + f(i + 1, j) / f(j + 1, 8); // A + B / C == N
if(g == N)ans++;
}
}
}while(std::next_permutation(a.begin(), a.end()));
// 枚举a的所有排列,打乱a数组中1-9的位置
std::cout << ans <<'\n';
return 0;
}
reference:
https://wenku.csdn.net/answer/7mxkew7uyk#
STL中关于全排列next_permutation以及prev_permutation的用法 - Xenny - 博客园 (cnblogs.com)
STL next_permutation和prev_permutation 算法原理和自行实现_next_permutation实现思想-CSDN博客
int型整数转换为数组,数组转换为int型整数_c++ int 元转int数组-CSDN博客
【C++】C++11的std::array的详细剖析-CSDN博客
lambda 表达式——匿名函数 auto i= [ ] () { };_lamda表达式auto-CSDN博客
Lambda 表达式 - OI Wiki (oi-wiki.org)
const int、const int *、int *cosnt、const int * const、const int &的区别_c++ const int*&-CSDN博客
“指针常量引用” , int const*,const int* ,const int*& ,int* const&区别详解_* const &-CSDN博客