// μ°Έκ³ λ‘ μ΄ μκ³ λ¦¬μ¦μ 10μ΄ μ΄μ 걸리λ κ±°λΌ μ λ΅μ λ΄μ§λ§ UVa μμλ μκ°μ΄κ³Όλ‘ μ€ν¨ν©λλ€. ^^γ
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string.h>
#include <string>
using namespace std;
// μ²΄μ€ ν
μ΄λΈ
// reserveTable: λΉμμ΄ λμΈ μμΉμ '1'μ΄μ μ₯λκ³ κ·Έλ μ§ μλ€λ©΄ '0' μ΄ μ μ₯λλ€.
// table: λΉμμ΄ κ³΅κ²©ν μ μλ μμΉμ '1'μ΄ μ μ₯λκ³ κ·Έλ μ§ μλ€λ©΄ '0'μ΄ μ μ₯λλ€.
class CTable
{
public:
CTable(int tableCnt)
{
m_tableCnt = tableCnt;
}
virtual ~CTable()
{
}
public:
int m_Table[ 8][ 8];
int m_tableCnt;
public:
void InitTable()
{
memset(m_Table, 0, sizeof(m_Table));
}
void CopyFrom(CTable *srcTable)
{
if (srcTable->m_tableCnt != m_tableCnt)
return;
memcpy(m_Table, srcTable->m_Table, sizeof(m_Table));
}
bool CanPositionBishop( int x, int y)
{
if (1 == m_Table[ x][ y])
return false;
return true;
}
};
// λΉμμ΄ μμΉν μμμ μ μ₯νκ³ , 곡격ν μ μλ μμμ '1'λ‘ μ€μ ν΄μ
// λ€λ₯Έ λΉμμ΄ μμΉνμ§ λͺ»νκ² νλ€.
void SetBishopPos( CTable &reserveTable, CTable &table, int x, int y)
{
reserveTable.m_Table[ x][ y] = 1;
int i=0, k=0;
while (i < table.m_tableCnt && k < table.m_tableCnt)
{
if ( table.m_tableCnt > x+i && table.m_tableCnt > y+k)
table.m_Table[ x+i][ y+k] = 1;
if ( table.m_tableCnt > x+i && 0 <= y-k)
table.m_Table[ x+i][ y-k] = 1;
if ( 0 <= x-i && table.m_tableCnt > y+k)
table.m_Table[ x-i][ y+k] = 1;
if ( 0 <= x-i && 0 <= y-k)
table.m_Table[ x-i][ y-k] = 1;
++i;
++k;
}
}
bool CanPositionBishop( CTable &reserveTable, CTable &table, int x, int y)
{
if (!table.CanPositionBishop(x, y))
return false;
if (!reserveTable.CanPositionBishop(x, y))
return false;
return true;
}
bool IsSolution( CTable &reserveTable, CTable &table, int x, int y)
{
return CanPositionBishop(reserveTable, table, x, y);
}
// reserveTable : λΉμμ΄ μ΄λ―Έ μμΉνμ μ΄ μλ κ³³μ μ μ₯νλ€.
// table : λΉμμ 곡격 μμμ μ μ₯νλ€.
int SearchSolution(int bishopsCount, CTable &reserveTable, CTable &table)
{
if (bishopsCount <= 0)
return 1;
int totalCount = 0;
// pCopyReserve: λΉμμ΄ μμΉν μ리λ λ€μ μμΉνμ§ λͺ»νλ€. λ°±νΈλνΉλ λ μ΄κΈ°νλλ€.
// pCopyTable: μ¬κ·νΈμΆλ λλ§λ€ μ΄κΈ°ν λμ΄μΌ νλ€. 곡격μμμ λΉμμ΄ μμΉν λλ§λ€ μ΄κΈ°ν λμ΄μΌνκΈ° λλ¬Έμ΄λ€.
CTable copyReserve = reserveTable;
CTable copyTable = table;
for (int x=0; x < copyTable.m_tableCnt; ++x)
{
for (int y=0; y < copyTable.m_tableCnt; ++y)
{
int count = 0;
if (IsSolution(copyReserve, copyTable, x, y))
{
SetBishopPos(copyReserve, copyTable, x, y);
count = SearchSolution(bishopsCount-1, copyReserve, copyTable);
copyTable = table;
}
else
{
}
totalCount += count;
}
}
return totalCount;
}
int main(int argv, char *argc[])
{
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
string line;
while ( getline(cin, line) )
{
istringstream iss(line);
int tableCnt, bishopCnt;
iss >> tableCnt >> bishopCnt;
if (tableCnt > 0 && bishopCnt > 0)
{
CTable reserveTable(tableCnt);
CTable table(tableCnt);
reserveTable.InitTable();
table.InitTable();
int cnt = SearchSolution(bishopCnt, reserveTable, table);
cout << cnt << endl;
}
}
return 1;
}
#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>
using namespace std;
class Main
{
public:
Main( istream& stm ) : m_stmIn( stm ), m_n( -1 ) {}
void Solve();
protected:
void Init( int n );
bool IsASolution( int a[], int k, int n );
void Backtrack( int a[], int k, int input );
void BuildCandidates( int a[], int k, int input, int c[], int& nCandidates );
//------------------------------------------------------------------------
istream& m_stmIn; // νμΌμ
λ ₯ or STDIN μ
λ ₯.
int m_n; // 체μ€νμ ν¬κΈ°
int m_numPosition; // = m_n * m_n
int m_count; // μ루μ
μ κ°μ.
int idToAxis[64][2]; // 체μ€νμ μμΉidλ₯Ό μ’νλ‘ λ°κΎΌ κ°.
};
void Main::Init( int n )
{
m_count = 0;
if( m_n != n )
{
m_n = n;
m_numPosition = m_n * m_n;
for( int i = 0; i < m_numPosition; i++ )
{
idToAxis[i][0] = i / m_n;
idToAxis[i][1] = i % m_n;
}
}
}
void Main::Backtrack( int a[], int k, int input )
{
int c[64];
int nCandidates = 0;
if( IsASolution( a, k, input ) )
{
m_count++;
return;
}
else
{
BuildCandidates( a, k, input, c, nCandidates );
for( int i = 0; i < nCandidates; i++ )
{
a[k] = c[i];
Backtrack( a, k + 1, input );
}
}
}
void Main::BuildCandidates( int a[], int k, int input, int c[], int& nCandidates )
{
nCandidates = 0;
// μ΄λ―Έ λΉμμ΄ μΆ©λΆν μμΉνλ€λ©΄ λμ΄μ μ§νν νμ μλ€.
if( k >= input )
return;
for( int i = (k == 0 ? 0 : a[k-1]+1); i < m_numPosition; i++ )
{
int canX = idToAxis[i][0];
int canY = idToAxis[i][1];
bool bEnable = true;
for( int j = 0; j < k; j++ )
{
int bishopX = idToAxis[a[j]][0];
int bishopY = idToAxis[a[j]][1];
if( abs(canX - bishopX) == abs(canY - bishopY) ) // λκ°μ 체ν¬
{
bEnable = false;
break;
}
}
if( bEnable )
c[nCandidates++] = i;
}
}
void Main::Solve()
{
int n, k;
while( true )
{
m_stmIn >> n >> k;
m_stmIn.get();
if( n == 0 && k == 0 )
return;
Init( n );
int bishops[64];
Backtrack( bishops, 0, k );
cout << m_count << endl;
}
}
bool Main::IsASolution( int a[], int k, int n )
{
return k == n;
}
int main( int argc, char* argv[] )
{
if( argc > 1 ) // λͺ
λ Ήν μΈμλ₯Ό λ°λλ€λ©΄ ν΄λΉ μ΄λ¦μ νμΌμ μΈνμΌλ‘ μΌλλ€.
{
ifstream fstm( argv[1] );
Main g( fstm );
g.Solve();
}
else // κ·Έλ₯ μ€ννλ©΄ νμ€μ
λ ₯μΌλ‘ μΈνμ λ°μ.
{
Main g( cin );
g.Solve();
}
return 0;
}