algorithm little bishops - andstudy/forge GitHub Wiki

kukuman

  • ๋ฐฑํŠธ๋ž˜ํ‚น์„ ์ดํ•ด ํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๋ฌธ์ œ์˜€๋˜๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์ง‘์ฐฉํ•˜๋‹ค๋ณด๋‹ˆ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ๊ณผ ๊ตฌ์กฐ๊ฐ€ ๊ทน์•… ์ž…๋‹ˆ๋‹ค. ใ… ใ…  ์ถ”ํ›„์— ๋ฆฌํŒฉํ† ๋ง ํ•ด์•ผ๋ ๋“ฏ ๋œ๋œ

    • ์žฌ๊ท€๋ฅผ ์•ˆ์“ฐ๊ณ  ํ’€์ˆ˜๋„ ์žˆ์„๊ฑฐ ๊ฐ™์€๋ฐ ใ…‹ ๋ ๊นŒ์š”? ใ…‹ ๋‹ด์— ์‹œ๋„ํ•ด๋ด์•ผ ๋  ๋“ฏ
  • ์ž…์ถœ๋ ฅ ์ฒ˜๋ฆฌ๋Š” ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค ใ…‹

  • JAVA

      import java.util.ArrayList;
      
      
      public class ChessBoard {
      	private int n;
      	private int checkCount = 0;
      	public ChessBoard(int n) {
      		this.n = n;
      	}
      	public boolean isAttachPos(int i, int j) {
      		int difWidth = Math.abs(i/n-j/n); //์œ„์•„๋ž˜์ฐจ์ด
      		int iPos = (i%n);
      		int jPos = (j%n);
      		return iPos==(jPos+difWidth) ||  iPos==(jPos-difWidth);
      	}
      	public int getSafeCount(int k) {
      		int [] curData = new int[k];
      		checkCount = 0;
      		backTracking(curData, 0, k);
      		return checkCount;
      	}
      	 
      	private void backTracking(int [] curData , int k, int i){
      		if(k==i){
      			processSolution(curData);
      		}else{
      			Integer [] candidates = makeCandidates(curData,k,i);
      			k++;
      			for(int cadidate : candidates){
      				curData[k-1] = cadidate;
      				backTracking(curData, k, i);
      			}
      		}
      		
      	}
      	private Integer [] makeCandidates(int[] curData,int k, int i) {
      		ArrayList<Integer> candidates = new ArrayList<Integer>(i);
      		//์ฒ˜์Œ ์‹œ์ž‘์€ ๋ชจ๋“  ๊ฐ’์ด ํ›„๋ณด๊ฐ€ ๋จ
      		if(k==0){
      			for(int j=0;j<n*n;j++){
      				candidates.add(j);
      			}
      		}
      		else{ //curData์— ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ธฐ์กด๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ๊ฐ’์ธจ ์ฐพ์Œ
      			//์ƒˆ๋กœ์šด ํ›„๋ณด ๋Š” ์ด์ „ ๊ฐ’๋ณด๋‹ค ํฌ๊ณ  ๊ธฐ์กด์˜ ๋ฐ์ดํ„ฐ์™€ Attacking Pos๊ฐ€ ๋˜์ง€ ์•Š์œผ๋ฉด ๋œ๋‹ค.
      			for(int j=curData[k-1];j<n*n;j++){
      				boolean allSafe = true;
      				for(int z=0;z<k;z++){
      					int comVal = curData[z];
      					if(isAttachPos(comVal, j)){
      						allSafe = false;
      						break;
      					}
      				}
      				if(allSafe){
      					candidates.add(j);
      				}
      			}
      		}
      		Integer [] a = new Integer[candidates.size()];
      		return (Integer [])candidates.toArray(a);
      	}
      	
      	private void processSolution(int[] curData) {
      		
      		checkCount ++;
      		/*StringBuilder builder = new StringBuilder();
      		for(int val : curData){
      			builder.append(val);
      			builder.append(" ");
      		}
      		System.out.println(builder.toString());*/
      	}
      
      }
    
  • TEST CASE

      import junit.framework.TestCase;
      
      
      public class BisopTestCase extends TestCase {
      	public void testIsAttackPos(){
      		/*
      		 * 012
      		 * 345
      		 * 678
      		 * 
      		 */
      		ChessBoard board = new ChessBoard(3);
      		assertTrue(board.isAttachPos(0,0));
      		assertFalse(board.isAttachPos(0,1));
      		assertFalse(board.isAttachPos(0,2));
      		assertFalse(board.isAttachPos(0,3));
      		assertTrue(board.isAttachPos(0,4));
      		assertFalse(board.isAttachPos(0,5));
      		assertFalse(board.isAttachPos(0,6));
      		assertFalse(board.isAttachPos(0,7));
      		assertTrue(board.isAttachPos(0,8));
      		assertTrue(board.isAttachPos(1,5));
      		assertTrue(board.isAttachPos(0,8));
      		assertTrue(board.isAttachPos(4,0));
      		assertTrue(board.isAttachPos(6,4));
      		assertTrue(board.isAttachPos(0,8));
      	}
      	
      	public void testSafeCount(){
      		ChessBoard board = new ChessBoard(4);
      		assertEquals(260, board.getSafeCount(4));
      		ChessBoard board2 = new ChessBoard(8);
      		assertEquals(5599888, board2.getSafeCount(6));
      	}
      	
      }
    

ParkPD

  • ๋˜ Time limit exceeded ๊ฐ€!!

  • ๋ญ”๊ฐ€ ์š”๋ น์ด ์—†๋Š” ๊ฑธ๊นŒ.. ๋ƒ ..

      /* @JUDGE_ID:parkpd 110401 Cpp "test" */
      
      /* @BEGIN_OF_SOURCE_CODE */
      
      #include <iostream>
      #include <vector>
      #include <set>
      #include <string>
      #include <strstream>
      #include <algorithm>
      #include <map>
      #include <math.h>
      
      //#define _UNIT_TEST
      
      using namespace std;
      
      namespace ATUtil
      {
      
      bool IsInRange(int value, int from, int to)
      {
      	return (from <= value) && (value <= to);
      }
      
      int ConvertToIndex(char c)
      {
      	if ('a' <= c && c <= 'z')
      	{
      		return c - 'a';
      	}
      	else
      	{
      		return -1;
      	}
      }
      
      char ConvertToChar(int i)
      {
      	return (char)i + 'a';
      }
      
      typedef map<int, int> IntDB;
      typedef vector<int> Ints;
      
      };
      
      using namespace ATUtil;
      
      #ifdef _UNIT_TEST
      
      #include "../UnitTest++/src/UnitTest++.h"
      
      int main()
      {
      	UnitTest::RunAllTests();
      
      	char temp;
      	cin >> temp;
      
      	return 0;
      }
      
      #endif
      
      // code implement
      
      namespace ATCode
      {
      
      ///////////////////////////////////////////////////////////////
      // CLittleBishops
      class CLittleBishops
      {
      public:
      	CLittleBishops(int n, int b) : m_Size(n), m_Boards(m_Size * m_Size), m_Bishops(b), m_Result(0) 
      	{
      		for (int r = 0; r < 8; ++r)
      		{
      			for (int c = 0; c < 8; ++c)
      			{
      				m_Board[r][c] = false;
      			}
      		}
      	}
      	
      	int Result();
      	void Find(int nBishopIndex, int startPos);
      	bool CheckAndPutBishop(int nBishopIndex, int startPos);
      	void RemoveBishop(int pos);
      	void GetRowCol(int pos, int& r, int& c) const;
      
      protected:
      	const int m_Size;
      	const int m_Boards;
      	const int m_Bishops;
      	int m_Result;	
      	bool m_Board[8][8];
      };
      
      int CLittleBishops::Result()
      {
      	m_Result = 0;
      
      	for (int i = 0; i < m_Boards; ++i)
      	{
      		Find(1, i);
      	}
      
      	return m_Result;
      }
      
      void CLittleBishops::Find(int nBishopIndex, int startPos)
      {
      	if (!CheckAndPutBishop(nBishopIndex, startPos))
      	{
      		return;
      	}
      	
      	if (m_Bishops <= nBishopIndex)	// ๋‹ค ์ฐพ์•˜๋‹ค.
      	{
      		++m_Result;
      	}
      	else	// startPos ์— ๋น„์ˆ ํ•˜๋‚˜ ๋†“์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‚˜๋จธ์ง€ ์ผ€์ด์Šค์— ๋Œ€ํ•ด์„œ backtrack ํ•œ๋‹ค.
      	{	
      		for (int i = startPos + 1; i < m_Boards; ++i)
      		{
      			Find(nBishopIndex + 1, i);
      		}
      	}
      			
      	// startPos ์— ๋†“๊ณ  ํ•ด ๋ณผ ๊ฑฐ ๋‹ค ํ•ด ๋ดค๋‹ค. ์ œ๊ฑฐํ•ด์ฃผ์ž.
      	RemoveBishop(startPos);
      }
      
      // nBishopIndex : 1 ~ m_Bishops ๊นŒ์ง€
      bool CLittleBishops::CheckAndPutBishop(int nBishopIndex, int startPos)
      {
      	if (m_Boards < startPos + (m_Bishops - nBishopIndex))		// ํ˜„์žฌ ์œ„์น˜ + ๋‚จ์€ ๋น„์ˆ ๊ฐฏ์ˆ˜๊ฐ€ ๋„˜์น˜๋ฉด return
      	{
      		return false;
      	}
      
      	int r, c;
      	GetRowCol(startPos, r, c);
      
      	if (m_Board[r][c])		// ์ด๋ฏธ bishop ์ด ๋“ค์–ด์žˆ๋‹ค.
      	{
      		return false;
      	}
      
      	// ๋Œ€๊ฐ์„  ํ…Œ์ŠคํŠธ.
      	int test_r, test_c;
      	//for (int i = -1; i <= 1; i += 2)	// ์ตœ์ ํ™” 1 - ์•„๋ž˜๋กœ ๊ฒ€์‚ฌํ•  ํ•„์š” ์—†์Œ.
      	{
      		for (int j = -1; j <= 1; j += 2)	
      		{
      			// ํ…Œ์ŠคํŠธ cursor ์œ„์น˜ ์ดˆ๊ธฐํ™”
      			test_r = r;
      			test_c = c;
      
      			while(1)
      			{
      				// ๋Œ€๊ฐ์„ ์œผ๋กœ ์œ„์น˜ ์ด๋™
      				//test_r += i;
      				test_r -= 1;		// ์ตœ์ ํ™” 1
      				test_c += j;
      
      				// ๊ฒ€์‚ฌ
      				if (IsInRange(test_r, 0, m_Size - 1) && IsInRange(test_c, 0, m_Size - 1))
      				{
      					if (m_Board[test_r][test_c])	// ๋Œ€๊ฐ์„ ์— bishop ์ด ์žˆ๋‹ค.
      					{
      						return false;
      					}
      				}
      				else
      				{
      					break;
      				}
      			}
      		}
      	}
      
      	m_Board[r][c] = true;
      
      	return true;
      }
      
      void CLittleBishops::RemoveBishop(int pos)
      {
      	int r, c;
      	GetRowCol(pos, r, c);
      	m_Board[r][c] = false;
      }
      
      void CLittleBishops::GetRowCol(int pos, int& r, int& c) const
      {
      	r = pos / m_Size;
      	c = pos - (r * m_Size);
      }
      
      ///////////////////////////////////////////////////////////////
      // CConsole
      class CConsole
      {
      public:
      	static void ConsoleTest(istream& input, ostream& output);
      };
      
      void CConsole::ConsoleTest(istream& input, ostream& output)
      {
      	int scenarioIndex = 1;
      
      	while (1)
      	{
      		int nSize = 0;
      		int nBishops = 0;
      	
      		input >> nSize >> nBishops;
      
      		if ((0 == nSize) && (0 == nBishops))
      		{
      			break;
      		}
      
      		CLittleBishops bishop(nSize, nBishops);
      		output << bishop.Result() << "\n";
      	}
      };
      
      }
      
      using namespace ATCode;
      
      #ifndef _UNIT_TEST
      
      int main()
      {
      	CConsole::ConsoleTest(cin, cout);
      
      	return 0;
      }
      
      #else
      
      // tests
      
      struct FixtureBase
      {
      	FixtureBase() : b_2_1(2, 1), b_2_2(2, 2), b_4_1(4, 1)
      	{
      	}
      
      	CLittleBishops b_2_1;
      	CLittleBishops b_2_2;
      	CLittleBishops b_4_1;
      
      	int r, c;
      	stringstream input;
      	stringstream output;
      };
      
      TEST_FIXTURE(FixtureBase, Result)
      {
      	CHECK_EQUAL(4, b_2_2.Result());
      	
      	CLittleBishops b_4_4(4, 4);
      	CHECK_EQUAL(260, b_4_4.Result());
      
      	CLittleBishops b_8_6(8, 6);
      	CHECK_EQUAL(5599888, b_8_6.Result());
      }
      
      TEST_FIXTURE(FixtureBase, GetRowCol)
      {
      	CHECK_EQUAL(4, b_2_1.Result());
      		
      	b_2_1.GetRowCol(1, r, c);
      	CHECK(r == 0 && c == 1);
      	b_2_1.GetRowCol(2, r, c);
      	CHECK(r == 1 && c == 0);
      
      	CHECK_EQUAL(16, b_4_1.Result());
      
      	b_4_1.GetRowCol(1, r, c);
      	CHECK(r == 0 && c == 1);
      	b_4_1.GetRowCol(5, r, c);
      	CHECK(r == 1 && c == 1);
      }
      
      // 0 : Bishop ์œ„์น˜
      // OO
      // XX
      TEST_FIXTURE(FixtureBase, CheckAndPutBishop1)
      {
      	CHECK(b_2_2.CheckAndPutBishop(1, 0));
      	CHECK(!b_2_2.CheckAndPutBishop(2, 0));
      	CHECK(b_2_2.CheckAndPutBishop(2, 1));
      	CHECK(!b_2_2.CheckAndPutBishop(2, 2));
      	CHECK(!b_2_2.CheckAndPutBishop(2, 3));
      }
      
      // XO
      // X0
      TEST_FIXTURE(FixtureBase, CheckAndPutBishop2)
      {
      	CHECK(b_2_2.CheckAndPutBishop(1, 1));
      	CHECK(!b_2_2.CheckAndPutBishop(2, 2));
      	CHECK(b_2_2.CheckAndPutBishop(2, 3));
      }
      
      TEST_FIXTURE(FixtureBase, ConsoleTest1)
      {
      	input << 
      		"4 4\n"
      		"0 0\n";
      	CConsole::ConsoleTest(input, output);
      	CHECK_EQUAL("260\n", output.str());
      }
      
      #endif
      
      /* @END_OF_SOURCE_CODE */
    

Outbreak

๋ฌธ์ œ ์š”์•ฝ

  • n by n์˜ ์ฒด์ŠคํŒ์— k๊ฐœ์˜ ๋น„์ˆ์ด ์„œ๋กœ ๊ณต๊ฒฉ๋ฐ›์ง€ ์•Š๋„๋ก ๋†“๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋Š”?

๋ฌธ์ œ ํ•ด๊ฒฐ ไธญ

  • ๊ฒฐ๊ตญ ์žฌ๊ท€๋ฅผ ์ด์šฉํ•œ ๋ฐฑํŠธ๋ž˜ํ‚น
  • ๋น„์ˆ์˜ ๊ณต๊ฒฉ ๊ฐ€๋Šฅ์€ ๊ฐ„๋‹จํ•œ ์ˆ˜์‹ ํ™œ์šฉ
    • y - x = d
    • y + x = d
  • ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ฒด์ŠคํŒ์„ 1์ฐจ์› ๋ฐฐ์—ด๋กœ ๊ณ„์‚ฐ
  • 8x8 64๊ฐœ๊ฐ€ ์ตœ๋Œ€๋ฏ€๋กœ double ํ˜• ๋น„ํŠธ์—ฐ์‚ฐ ์‚ฌ์šฉ

์†Œ๊ฐ ไธญ

  • ์กธ๋ฆฌ๋”๋ผ๋„ ๋ฐค์— ํ•˜๊ณ  ์ž˜ ๊ฒƒ.
  • ์•„์นจ์— ํ•˜๋‹ˆ ์ž˜ ์•ˆ๋˜๋„ค์š” ^^;
  • ๊ฑ C#์œผ๋กœ ํ•  ๊ฑธ.. ๊ฐ‘์ž๊ธฐ submit ์š•์‹ฌ์ด..
  • ์ด์ œ ์ง‘์—์„œ ์ถœ๋ฐœํ•˜๋‹ˆ 40๋ถ„์ •๋„ ์ง€๊ฐ์ด์š”~ ํ;

ํ’€์ด ไธญ''' =

    /* @JUDGE_ID:present 110801 Cpp "LittleBishops" */
    
    /* @BEGIN_OF_SOURCE_CODE */
    
    #include <iostream>
    #include <map>
    #include <vector>
    
    using namespace std;
    
    #define _TDD
    
    // 1. > ์ง์„ ์˜ ๋ฐฉ์ •์‹์œผ๋กœ ํ‘ผ๋‹ค.
    //		๊ธฐ์šธ๊ธฐ๋Š” 1 ๊ณผ -1
    //		์ฆ‰, y = x + d  ๋˜๋Š” y = -x + d
    //		์ฆ‰, y - x = d ๋˜๋Š” y + x = d ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๊ฐ€ ๊ฐ™์ง€ ์•Š์œผ๋ฉด ๋จ.
    //		๋‘ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด d ๊ฐ€ ๋‹ค๋ฅด๋ฉด ํ‚ฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋จ.
    
    // 2. > 2์ฐจ์› ์ขŒํ‘œ๋ฅผ 1์ฐจ์›์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค!
    //		์ฒด์ŠคํŒ์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๊ฐ€ 8x8 ์ด๋ฏ€๋กœ 64๋น„ํŠธ double ํ˜• ์‚ฌ์šฉ
    //		๋น„ํŠธ์…‹ ์—ฐ์‚ฐ ํ™œ์šฉ
    
    namespace Solver
    {	
    	class Bishop
    	{
    	public:
    		Bishop(int x, int y) : X(x), Y(y){};
    
    		bool operator == ( Bishop const& rhs )
    		{					
    			return IsAttackable(X, Y, rhs.X, rhs.Y);			
    		}
    
    		static bool IsAttackable(int x1, int y1, int x2, int y2)
    		{
    			if( (y1-x1) == (y2-x2) || (y1-x1) == (y2+x2) )
    				return true;
    			
    			return false;
    		}
    
    	public:
    		int X, Y;
    
    	};
    
    	class Board
    	{
    	public:
    		Board(int n, int k) : w(n), h(n), max(k), result(0){}
    
    		int GetOneDimIndex( int x, int y)
    		{
    			return x*w + y;
    		}
    
    		int GetXFromOneDim( int index )
    		{
    			return index%w;
    		}
    
    		int GetYFromOneDim( int index )
    		{
    			return index/w;
    		}
    		
    		void SetBishops(double currentBoard, int cnt)
    		{	
    			if( cnt == max )
    			{			
    				result = result + 1;										
    				return;
    			}
    
    			// 64bit ์—ฐ์‚ฐ ์žฌ๊ท€
    				
    		}
    
    		int Find()
    		{		
    			result = 1;
    			return result;
    		}
    
    	private:
    		int w, h, max;
    	
    		// MastoJun ๋‹˜์ด ๋งŒ๋“ค์–ด ๋†“์€ BigNumber ์‚ฌ์šฉํ•˜๊ธฐ
    		int result;
    	};
    	
    	int Execute( int n, int k )
    	{	
    		Board board( n, k );
    		return board.Find();	
    	}
    }
    
    namespace Runner
    {
    	void Execute(istream& in, ostream& out)
    	{
    		int n = 0, k = 0;
    
    		do
    		{
    			in >> n >> k;
    
    			out << Solver::Execute(n,k) << endl;
    		}		
    		while( n != 0 || k != 0 );		
    	}
    }
    
    
    #ifdef _TDD
    #include "UnitTest++.h"
    
    using Solver::Bishop;
    using Solver::Board;
    
    TEST( Attackable )
    {
    	CHECK_EQUAL( true, Bishop::IsAttackable(1,1, 1,1) );
    	CHECK_EQUAL( true, Bishop::IsAttackable(1,1, 2,2) );
    	CHECK_EQUAL( true, Bishop::IsAttackable(1,1, 3,3) );
    
    	CHECK_EQUAL( false, Bishop::IsAttackable(1,1, 4,3) );
    	CHECK_EQUAL( false, Bishop::IsAttackable(1,1, 1,4) );
    }
    
    TEST( AttackableOperator)
    {
    	Bishop bs(0,0);
    	Bishop bss(1,1);
    	Bishop bsss(2,1);
    
    	CHECK_EQUAL( true, bs == bs );
    	CHECK_EQUAL( true, bs == bss );
    	CHECK_EQUAL( false, bs == bsss );
    }
    
    TEST( BoardOperation)
    {
    
    
    }
    
    TEST( 2x2 )
    {
    	Board bd(2,2);
    	
    	CHECK_EQUAL( 4, bd.Find() );
    }
    
    #endif // _TDD
    
    
    int main()
    {
    
    #ifdef _TDD	
    	UnitTest::RunAllTests();
    #else
    	Runner::Execute(cin, cout);
    #endif // _TDD
    	return 0;
    
    }
    
    /* @END_OF_SOURCE_CODE */
โš ๏ธ **GitHub.com Fallback** โš ๏ธ