mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-04 02:56:40 +08:00
Create magic_sequence.cpp
This commit is contained in:
74
backtracking/magic_sequence.cpp
Normal file
74
backtracking/magic_sequence.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* @brief [Magic sequence](https://www.csplib.org/Problems/prob019/)
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* @author [Jxtopher](https://github.com/jxtopher)
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
namespace backtracking {
|
||||
namespace magic_sequence {
|
||||
using sequence_t = std::vector<unsigned int>;
|
||||
|
||||
void print(const sequence_t& s) {
|
||||
for(auto item : s) std::cout << item << " ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// Check if it's a magic sequence
|
||||
bool is_magic(const sequence_t& s) {
|
||||
for(unsigned int i = 0; i < s.size(); i++)
|
||||
if(std::count(s.cbegin(), s.cend(), i) != s[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Filtering of sub-solutions
|
||||
// true if the sub-solution is valid otherwise false
|
||||
bool filtering(const sequence_t& s, unsigned int depth) {
|
||||
return std::accumulate(s.cbegin(), s.cbegin() + depth, static_cast<unsigned int>(0)) <=
|
||||
s.size();
|
||||
}
|
||||
|
||||
void solve(sequence_t& s, std::list<sequence_t>& ret, unsigned int depth = 0) {
|
||||
if(depth == s.size()) {
|
||||
if(is_magic(s)) ret.push_back(s);
|
||||
} else {
|
||||
for(unsigned int i = 0; i < s.size(); i++) {
|
||||
s[depth] = i;
|
||||
if(filtering(s, depth + 1)) solve(s, ret, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace magic_sequence
|
||||
|
||||
} // namespace backtracking
|
||||
|
||||
using namespace backtracking::magic_sequence;
|
||||
|
||||
static void test() {
|
||||
sequence_t s_magic = {6, 2, 1, 0, 0, 0, 1, 0, 0, 0};
|
||||
assert(is_magic(s_magic));
|
||||
|
||||
sequence_t s_not_magic = {5, 2, 1, 0, 0, 0, 1, 0, 0, 0};
|
||||
assert(!is_magic(s_not_magic));
|
||||
}
|
||||
|
||||
int main() {
|
||||
test();
|
||||
|
||||
for(unsigned int i = 2; i < 12; i++) {
|
||||
std::cout << "Solution for n = " << i << std::endl;
|
||||
std::list<sequence_t> r1;
|
||||
sequence_t s1(i, i);
|
||||
solve(s1, r1);
|
||||
for(auto item : r1) print(item);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user