/* vim: set ts=2 sts=2 sw=2 si foldmethod=marker: */ // {{{ includes // IO #include #include #include #include #include #include // Utility #include #include #include #include #include #include #include #include // Data structures #include #include #include #include #include #include #include #include // I want easy access to STL and things like hash_map using namespace std; using namespace std::tr1; // Needed for hash_map /* namespace __gnu_cxx { template<> struct hash { int operator()(const std::string& x) const { return hash()(x.c_str()); } }; } */ // }}} // {{{ utility routines and such // stolen from http://www.ddj.com/cpp/184403801 template class StringTok { public: StringTok(const T& seq, typename T::intype pos = 0) : seq_(seq) , pos_(pos) { } T operator()(const T& delim); private: const T& seq_; typename T::intype pos_; }; template T StringTok::operator()(const T& delim) { T token; if(pos_ != T::npos) { // start of found token typename T::intype first(seq_.find_first_not_of(delim.c_str(), pos_)); if (first != T::npos) { // length of found token typename T::intype num(seq_.find_first_of(delim.c_str(), first) - first); // do all the work off to the side token = seq_.substr(first, num); // done; now commit using // nonthrowing operations only pos_ = first + num; if (pos_ != T::npos) ++pos_; if (pos_ >= seq_.size()) pos_ = T::npos; } } return token; } // stolen from http://www.gotw.ca/gotw/029.htm for case-insensitive lexicographic compares struct ci_char_traits : public std::char_traits { static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); } static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); } static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); } static int compare(const char* s1, const char* s2, int n) { return strncasecmp(s1, s2, n); } static const char* find(const char* s, int n, char a) { while(n-- > 0 && toupper(*s) != toupper(a)) { ++s; } return s; } }; // no boost makes c++ angry; lexical cast comes in handy for string <=> int conversion without expliucitly writing out the streams all the time. template T lexical_cast(const S& arg) { stringstream interpreter; T result; if (!(interpreter << arg) || !(interpreter >> result) || !(interpreter >> std::ws).eof()) throw logic_error("bad lexical_cast"); return result; } // }}} // {{{ utility typedefs typedef vector vs; typedef vector vi; typedef std::basic_string ci_string; // }}} // {{{ problem-specific typedefs // }}} int n, k, nn, valid_count, marked, last; bool *placed; void solve_helper(); void state() { #if o for (int i(0); i < nn; i++) { if (i && !(i%n)) cerr << endl; cerr << (placed[i] ? "[]" : "__"); } cerr << endl; #endif } bool last_valid() { assert(placed[last]); int d1(n + 1), d2(n - 1); if (d1 && last % n) // up left { for (int i(last - d1); i >= 0; i -= d1) { if (placed[i]) { state(); return false; } if (!(i % n)) break; } } if (d2 && (last % n) != (n - 1)) // up right { for (int i(last - d2); i >= 0; i -= d2) { if (placed[i]) { state(); return false; } if (i % n == n - 1) // once we hit edge, stop { break; } } } return true; } void recurse(int i) { assert(!placed[i]); int old_last(last); placed[i] = true; marked++; last = i; solve_helper(); marked--; placed[i] = false; last = old_last; } void solve_helper() { // better have at least one, or else people gonna die assert(marked); if (!last_valid()) return; // at the right number, is the solution valid? if (marked == k) { valid_count++; state(); } // recurse and add another else { for (int i(last + 1); i < nn; ++i) recurse(i); } } void solve() { nn = n * n; valid_count = marked = 0; last = -1;; placed = new bool[nn]; for (int i(0); i < nn; ++i) placed[i] = false; for (int i(0); i < nn; ++i) { recurse(i); } cout << valid_count << endl; delete[] placed; } int main() { while (cin >> n >> k, n != 0) { solve(); // only allow addition of queens at a higher a[i] for i } return 0; }