programming challenges 2012 little bishops - andstudy/forge GitHub Wiki

μ΄μž¬μ •

// 참고둜 이 μ•Œκ³ λ¦¬μ¦˜μ€ 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;
}

μ΅œμ„±κΈ°

  • λΉ„μˆ 문제 ν’€μ–΄λ΄€μŠ΅λ‹ˆλ‹€.
  • 이것도 온라인 μ±„μ μ—μ„œλŠ” 'Time limit exceeded'κ°€ λœ¨λ„€μš” γ…‘γ…œ)...

μ†ŒμŠ€μ½”λ“œ

#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;
}
⚠️ **GitHub.com Fallback** ⚠️