algorithm the necklace - andstudy/forge GitHub Wiki

kukuman

  • ์‹ธ์ดํด์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋Š” ๊ฐ ์ƒ‰์ƒ์˜ ๊ฐœ์ˆ˜์˜ ํ•ฉ์ด ์ง์ˆ˜์ธ์ง€๋ฅผ ์ฑ„ํฌํ•˜๋Š”๊ฑธ๋กœ ํ•จ

  • nacklace

  • ํ—›์  ํˆฌ์„ฑ์ด์•ผ... ๋ฒ„๋Ÿญ!

      public void testTwoCircle() {
              	NacklaceMaker nacklace = new NacklaceMaker();
              	nacklace.add(1,2);        	
              	nacklace.add(1,2);        	
              	nacklace.add(4,5);        	
              	nacklace.add(4,5);        	
              	ArrayList<Bead> beads =  nacklace.makeNacklace();
              	assertFalse(nacklace.isCircle());
              	checkBeads(beads);
              }
              
              public void testLine() {
              	NacklaceMaker nacklace = new NacklaceMaker();
                  nacklace.add(2,3);
                  nacklace.add(2,3);
                  nacklace.add(3,4);
                  nacklace.add(3,4);
                  nacklace.add(4,5);
                  nacklace.add(4,5);
                  ArrayList<Bead> beads =  nacklace.makeNacklace();
                  assertEquals(6,beads.size());
                  checkBeads(beads);
              }
    
  • JAVA

      import java.util.ArrayList;
      
      
      public class NacklaceMaker {
      	private ArrayList<Bead> beads;
      	public NacklaceMaker(){
      		beads = new ArrayList<Bead>();
      	}
      	public void add(int leftColor, int rightColor) {
      		Bead bead = new Bead(leftColor,rightColor);
      		beads.add(bead);
      	}
      	
      	public boolean isCircle() {
      		int [] colorsCount = new int[51];
      		for(int i=1;i<colorsCount.length;i++){
      			colorsCount[0] = 0;
      		}
      		//์–‘์ชฝ์˜ ์นผ๋ผ์˜ ํ•ฉ์„ ์ €์žฅํ•œ๋‹ค.
      		for(Bead bead : beads){
      			colorsCount[bead.getLeftColor()]++;
      			colorsCount[bead.getRightColor()]++;
      		}
      		
      		//๋ชจ๋‘ ์—ฐ๊ฒฐ ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ž…๋ ฅ๋œ  ์นผ๋ผ์˜ ํ•ฉ์€  ๋ชจ๋‘ 2๋กœ ๋‚˜๋ˆ ๋–จ์–ด์ ธ์•ผ ๋œ๋‹ค.
      		for(int i=1;i<colorsCount.length;i++){
      			if((colorsCount[i]%2)!=0){
      				return false;
      			}
      		}
      		return true;
      	}
      	public ArrayList<Bead> makeNacklace() {
      		ArrayList<Bead> resultList = new ArrayList<Bead>(beads.size()); //๊ฒฐ๊ณผ
      		boolean [] isTraveled = new boolean[beads.size()]; // ์ˆœํšŒ ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€
      		for(int i=0;i<isTraveled.length;i++){
      			isTraveled[i] = false;
      		}
      		
      		//์‹œ์ž‘์€ ์ฒซ๋ฒˆ์งธ์˜ ์˜ค๋ฅธ์ชฝ์ƒ‰
      		Bead curBead = getNextBead(beads.get(0).getLeftColor(), isTraveled);
      		while(curBead != null){
      			resultList.add(curBead);
      			curBead = getNextBead(curBead.getRightColor(), isTraveled);
      		}
      		return resultList;
      	}
      	
      	private Bead getNextBead(int searchColor,boolean [] isTraveled){
      		for(int i=0;i<beads.size();i++){
      			if(!isTraveled[i]){
      				Bead curBean = beads.get(i);
      				if(curBean.getLeftColor() == searchColor || curBean.getRightColor() == searchColor){
      					if(curBean.getRightColor() == searchColor ){ //์˜ค๋ฅธ์ชฝ์ด ๊ฐ™์œผ๋ฉด ๋’ค์ง‘๋Š”๋‹ค
      						curBean.switchColor();
      					}
      					isTraveled[i] = true;
      					return curBean;
      				}
      			}
      		}
      		return null;
      	}
      	
      
      }
      
      
      public class Bead {
      	private int leftColor;
      	private int rightColor;
      	
      	public Bead(int color1, int color2) {
      		this.leftColor = color1;
      		this.rightColor = color2;
      	}
      
      	public void switchColor(){
      		int temp = leftColor;
      		leftColor = rightColor;
      		rightColor = temp;
      	}
      	
      	public int getLeftColor() {
      		return leftColor;
      	}
      
      	public int getRightColor() {
      		return rightColor;
      	}
      
      	public boolean hasColor(int searchColor) {
      		return false;
      	}
      	
      	public String toString(){
      		return leftColor + " " + rightColor;
      	}
      	
      }
    
  • TestCase

      import java.util.ArrayList;
      
      import junit.framework.TestCase;
      
      
      public class NacklaceTestCase extends TestCase {
      	public void testCheckCircle(){
      		NacklaceMaker nacklace = new NacklaceMaker();
      		nacklace.add(1,2);
      		nacklace.add(2,3);
      		assertFalse(nacklace.isCircle());
      	}
      	public void testCheckCircle2(){
      		NacklaceMaker nacklace = new NacklaceMaker();
      		nacklace.add(1,50);
      		nacklace.add(50,1);
      		assertTrue(nacklace.isCircle());
      	}
      	
      	public void testBeadSwitch(){
      		Bead bead = new  Bead(1,2);
      		bead.switchColor();
      		assertEquals(bead.getLeftColor(), 2);
      		assertEquals(bead.getRightColor(), 1);
      	}
      	public void testMakeNacklace(){
      		NacklaceMaker nacklace = new NacklaceMaker();
      		nacklace.add(2,1);
      		nacklace.add(2,2);
      		nacklace.add(3,4);
      		nacklace.add(3,1);
      		nacklace.add(2,4);
      		ArrayList<Bead> beads =  nacklace.makeNacklace();
      		assertEquals(5,beads.size());
      		checkBeads(beads);
      	}
      	private void checkBeads(ArrayList<Bead> beads){
      		int prvColor = beads.get(beads.size()-1).getRightColor();
      		for(Bead bead : beads){
      			System.out.println(bead);
      			assertEquals(prvColor, bead.getLeftColor());
      			prvColor = bead.getRightColor();
      		}
      		assertEquals(beads.get(0).getLeftColor(),beads.get(beads.size()-1).getRightColor());
      		
      	}
      }
    

ParkPD

  • Euler Cycle ์„ ์ด์šฉํ•ด์„œ ๋ฌธ์ œ ํ’€์—ˆ์Œ.
  • ํฐ ๋ฌธ์ œ ์—†์–ด๋ณด์ด๋Š”๋ฐ Wrong Answer ๋‚˜์˜ค๋Š” ๊ฑฐ ๋ณด๋ฉด, ๋ญ”๊ฐ€ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์•ˆ ํ•ด ์ค€ ๊ฑฐ ๊ฐ™๊ธฐ๋„... -.-;;;
    • ํฌ์ข…๋‹˜ ๋•๋ถ„์— ๋ฒ„๊ทธ ํ•˜๋‚˜ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค๋งŒ ์—ฌ์ „ํžˆ Wrong Answer ๊ฐ€ ๋‚˜์˜ค๋Š”๊ตฐ์š”

    • Programming-Challenges ํ™ˆํŽ˜์ด์ง€์˜ ๋ฌธ์ œ์ผ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Overall statistics๋ฅผ ๋ณด๋ฉด 152๋ช…์ด๋‚˜ Submit์„ ํ–ˆ๋Š”๋ฐ Best Time์— never solved๊ฐ€ ์ฐํ˜€์žˆ๋Š”๊ฑธ๋กœ ๋ด์„œ ์˜ค๋ฅ˜์ผ ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์š”. UVa์— ์ง์ ‘ ์ œ์ถœํ•ด ๋ด์•ผ ํ•˜๋Š”๋ฐ ์ €์ง€์‚ฌ์ดํŠธ๊ฐ€ ์—ฐ๊ฒฐ์ด ์•ˆ๋˜๋„ค์š”;

      /* @JUDGE_ID:parkpd 110401 Cpp "test" */
      
      /* @BEGIN_OF_SOURCE_CODE */
      
      #include <iostream>
      #include <vector>
      #include <set>
      #include <deque>
      #include <list>
      #include <stack>
      #include <string>
      #include <algorithm>
      #include <map>
      #include <limits>
      #include <assert.h>
      #include <iomanip>
      #include <math.h>
      
      //#define _UNIT_TEST
      
      #ifdef _UNIT_TEST
      #include <Windows.h>
      #endif
      
      using namespace std;
      
      // Minimum Spanning Tree -> Prim Algorithm ์„ ์ƒ๊ฐํ•˜๋ฉฐ ํ’€์—ˆ์Œ.
      
      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';
      	}
      
      #ifdef _UNIT_TEST
      	class CStopWatch
      	{
      	public:
      		CStopWatch()
      		{
      			m_StartTick = GetTickCount();		// gcc ์—์„œ ์•ˆ ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ
      		}
      
      		~CStopWatch()
      		{
      			cout << "Time passed : " << GetTickCount() - m_StartTick << " milisec.\n";
      		}
      
      		int m_StartTick;
      	};
      #endif
      
      	typedef map<int, int> IntDB;
      	typedef vector<int> Ints;
      	typedef list<int> IntList;
      
      };
      
      using namespace ATUtil;
      
      #ifdef _UNIT_TEST
      
      #include "../UnitTest++/src/UnitTest++.h"
      
      #ifdef max
      #undef max
      #endif
      
      int main()
      {
      	UnitTest::RunAllTests();
      
      	char temp;
      	cin >> temp;
      
      	return 0;
      }
      
      #endif
      
      // code implement
      
      namespace ATCode
      {
      	//////////////////////////////////////////////////////////////////////////
      	// CVertex
      	typedef list<int> VectexList;
      
      	class CVertex
      	{
      	public:
      		CVertex(int c) : m_Color(c), m_Checked(false) {}
      		int m_Color;
      		bool m_Checked;
      		
      		VectexList m_Neighbors;
      	};
      
      	//////////////////////////////////////////////////////////////////////////
      	// CGraph
      	class CGraph
      	{
      	public:
      		CVertex* GetOrCreate(int c)
      		{
      			VertexMap::iterator it = m_Graph.find(c);
      			if (it == m_Graph.end())
      			{
      				CVertex* p = new CVertex(c);
      				m_Graph.insert(make_pair(c, p));
      				return p;
      			}
      			else
      			{
      				return it->second;
      			}
      		}
      
      		template<typename InputIterator>
      		void AddEdges(InputIterator from, InputIterator to)
      		{
      			for (InputIterator it = from; it != to; it += 2)
      			{
      				AddEdge(*it, *(it + 1));
      			}
      		}
      
      		void AddEdge(int c1, int c2)
      		{
      			CVertex* pV1 = GetOrCreate(c1);
      			CVertex* pV2 = GetOrCreate(c2);
      			pV1->m_Neighbors.push_back(c2);
      			pV2->m_Neighbors.push_back(c1);
      		}
      
      		int Size() const { return (int)m_Graph.size(); }
      		bool IsEulerCycle()
      		{
      			if (m_Graph.empty())
      			{
      				return false;
      			}
      
      			// http://www.aistudy.com/math/koenigsberg_bridge_problem.htm
      			// ๊ทธ๋ž˜ํ”„ G ๊ฐ€ ์˜ค์ผ๋Ÿฌ ์‚ฌ์ดํด์„ ๊ฐ€์ง€๋ฉด, G ๋Š” ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  ๊ฐ ์ •์ ์€ ์ง์ˆ˜ ์ฐจ์ˆ˜์ด๋‹ค.
      			// G ๊ฐ€ ์—ฐ๊ฒฐ๋œ ๊ทธ๋ž˜ํ”„์ด๊ณ  ๋ชจ๋“  ์ •์ ์ด ์ง์ˆ˜ ์ฐจ์ˆ˜๋ฅผ ๊ฐ€์ง€๋ฉด G ๋Š” ์˜ค์ผ๋Ÿฌ ์‚ฌ์ดํด์„ ๊ฐ€์ง„๋‹ค.
      
      			// ๋ชจ๋“  ์ •์ ์ด ์ง์ˆ˜ ์ฐจ์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌ ์ค‘.
      			for (VertexMap::iterator it = m_Graph.begin(); it != m_Graph.end(); ++it)
      			{
      				CVertex* p = it->second;
      				if (p->m_Neighbors.size() % 2 == 1)
      				{
      					return false;
      				}
      			}
      
      			// G ๊ฐ€ ์—ฐ๊ฒฐ๋œ ๊ทธ๋ž˜ํ”„์ธ์ง€๋Š” ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์ง€?
      			// ์‹ ์žฅ ํŠธ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ๋ณด์ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค๋Š”๋ฐ?
      			// ๋„ˆ๋น„ ์šฐ์„  ํŠธ๋ฆฌ, ๊นŠ์ด ์šฐ์„  ํŠธ๋ฆฌ๋„ ์‹ ์žฅํŠธ๋ฆฌ๋‹ค.
      			// BFS ๋ฅผ ์จ ๋ณด์ž.
      			size_t checkedVertex = 0;
      			deque<int> queue;
      			queue.push_back(m_Graph.begin()->first);
      			while (!queue.empty())
      			{
      				int nodeIndex = queue.front();
      				queue.pop_front();
      				CVertex* p = m_Graph[nodeIndex];
      				if (p->m_Checked)
      				{
      					continue;
      				}
      
      				p->m_Checked = true;
      				checkedVertex++;
      
      				VectexList& neighbors = p->m_Neighbors;
      				for (VectexList::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
      				{
      					CVertex* pNode = m_Graph[*it];
      					queue.push_back(pNode->m_Color);
      				}
      			}
      
      			// BFS ๋กœ ๊ฐ€์ง€ ๋ชปํ•˜๋Š” vertex ๊ฐ€ ์žˆ๋‹ค. ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜์Œ.
      			if (checkedVertex < m_Graph.size())
      			{
      				return false;
      			}
      
      			return true;
      		}
      
      		void EraseFromList(VectexList& neighbors, int num)
      		{
      			for (VectexList::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
      			{
      				if (*it == num)
      				{
      					neighbors.erase(it);
      					return;	// ๋” ์ฐพ์„ ํ•„์š”๋„ ์—†๊ณ , iterator ๋„ ๋ฌดํšจํ™”๋˜๋ฏ€๋กœ ๋‚˜๊ฐ€์ž
      				}
      			}
      		}
      
      		bool FindEulerSubCycle(int node, stack<int>& intStack)
      		{
      			CVertex* pFrom = m_Graph[node];
      
      			while (!pFrom->m_Neighbors.empty())
      			{
      				CVertex* pTo = m_Graph[*(pFrom->m_Neighbors.begin())];
      				EraseFromList(pTo->m_Neighbors, pFrom->m_Color);
      				EraseFromList(pFrom->m_Neighbors, pTo->m_Color);
      				intStack.push(pTo->m_Color);
      				pFrom = pTo;
      			}
      
      			return true;
      		}
      
      		string EulerCycle()
      		{
      			stack<int> stackNum;
      			int startNode = m_Graph.begin()->first;
      			stackNum.push(startNode);
      			while (!stackNum.empty())
      			{
      				FindEulerSubCycle(startNode, stackNum);
      				while(!stackNum.empty())
      				{
      					// stack ๋˜์–ด ์žˆ๋Š” node ๋ฅผ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ธ๋‹ค.
      					// isolated ๋œ node ๋ผ๋ฉด, path ์— ์ถ”๊ฐ€ํ•œ ํ›„ ๋ฒ„๋ฆฌ๊ณ ,
      					// edge ๊ฐ€ ๋‚จ์•„ ์žˆ๋Š” node ๋ผ๋ฉด stack ์— ๋‘” ์ฑ„๋กœ ์ด์›ƒ node ๋กœ ํ™•์žฅ์‹œํ‚จ๋‹ค.
      					// [SedgeWick Part5]
      					startNode = stackNum.top();
      					CVertex* pStackedNode = m_Graph[startNode];
      					if (pStackedNode->m_Neighbors.empty())
      					{
      						stackNum.pop();
      						m_Path.push_back(startNode);
      					}
      					else
      					{
      						break;
      					}
      				}
      			}
      
      			char buf[1000];
      			string ret;
      
      			for (size_t i = 0; i < m_Path.size() - 1; ++i)
      			{
      				sprintf(buf, "%d %d\n", m_Path[i], m_Path[i + 1]);
      				ret.append(buf);
      			}
      
      			//sprintf(buf, "%d %d\n", m_Path[m_Path.size() - 1], m_Path[0]);
      			//ret.append(buf);
      
      			return ret;
      		}
      
      		typedef map<int, CVertex*> VertexMap;
      		VertexMap m_Graph;
      		vector<int> m_Path;
      	};
      
      	///////////////////////////////////////////////////////////////
      	// CConsole
      	class CConsole
      	{
      	public:
      		static void ConsoleTest(istream& input, ostream& output);
      	};
      
      	void CConsole::ConsoleTest(istream& input, ostream& output)
      	{
      		int testCount = 0;
      		input >> testCount;
      
      		for (int i = 0; i < testCount; ++i)
      		{
      			if (1 <= i)
      			{
      				output << "\n";
      			}
      
      			int num = 0;
      			input >> num;
      
      			CGraph graph;
      
      			int n1, n2;
      			for (int j = 0; j < num; ++j)
      			{
      				input >> n1 >> n2;
      				graph.AddEdge(n1, n2);
      			}
      
      			output << "Case #" << i + 1 << "\n";
      			if (!graph.IsEulerCycle())
      			{
      				output << "some beads may be lost\n";
      			}
      			else
      			{
      				// ํ•ด๋‹ต์€ ์žˆ๋‹ค. Euler Cycle ์„ ์ฐพ์ž.
      				output << graph.EulerCycle();
      			}
      		}
      	};
      
      }
      
      using namespace ATCode;
      
      #ifndef _UNIT_TEST
      
      int main()
      {
      	CConsole::ConsoleTest(cin, cout);
      
      	return 0;
      }
      
      #else
      
      // tests
      
      struct FixtureBase
      {
      	FixtureBase()
      	{
      	}
      
      	CGraph g;
      	stringstream input;
      	stringstream output;
      };
      
      TEST_FIXTURE(FixtureBase, IsEulerCycle3)
      {
      	int input[] = {1, 1, 1, 1, 1, 1, 1, 1};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(g.IsEulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, IsEulerCycle2)
      {
      	int input[] = {1, 2, 2, 2, 2, 3, 3, 1};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(g.IsEulerCycle());
      	g.AddEdge(3, 4);
      	CHECK(!g.IsEulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, IsEulerCycle1)
      {
      	int input[] = {2, 3, 2, 3, 3, 4, 3, 4, 4, 5, 4, 5};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(g.IsEulerCycle());
      	CHECK_EQUAL("2 3\n3 4\n4 5\n5 4\n4 3\n3 2\n", g.EulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, IsEulerCycle)
      {
      	int input[] = {1, 2, 1, 2, 4, 5, 4, 5};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(!g.IsEulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, EulerCycle)
      {
      	int input[] = {0, 1, 0, 2, 0, 5, 0, 6, 1, 2, 2, 3, 2, 4, 3, 4, 4, 5, 4, 6};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(g.IsEulerCycle());
      	CHECK_EQUAL("0 6\n6 4\n4 3\n3 2\n2 4\n4 5\n5 0\n0 2\n2 1\n1 0\n", g.EulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, EulerCycle1)
      {
      	int input[] = {1, 3, 1, 2, 1, 5, 2, 3, 2, 5, 2, 4, 3, 4, 4, 5, 3, 6, 4, 6, 4, 7, 5, 7, 1 ,4};
      	g.AddEdges(&input[0], &input[sizeof(input) / sizeof(int)]);
      	CHECK(g.IsEulerCycle());
      	CHECK_EQUAL("1 4\n4 7\n7 5\n5 4\n4 6\n6 3\n3 4\n4 2\n2 5\n5 1\n1 2\n2 3\n3 1\n", g.EulerCycle());
      }
      
      TEST_FIXTURE(FixtureBase, ConsoleTest2)
      {
      	input << 
      		"2\n"
      		"5\n"
      		"1 2\n"
      		"2 3\n"
      		"3 4\n"
      		"4 5\n"
      		"5 6\n"
      		"5\n"
      		"2 1\n"
      		"2 2\n"
      		"3 4\n"
      		"3 1\n"
      		"2 4\n";
      	CConsole::ConsoleTest(input, output);
      	CHECK_EQUAL( 
      		"Case #1\n"
      		"some beads may be lost\n"
      		"\n"
      		"Case #2\n"
      		"1 3\n"
      		"3 4\n"
      		"4 2\n"
      		"2 2\n"
      		"2 1\n", 
      		output.str());
      }
      
      #endif
      
      /* @END_OF_SOURCE_CODE */
      

CynicJJ

  • ํ•œ ์ƒ‰์ƒ ๊ตฌ์Šฌ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ๊ฐ€ ๋งŽ์•„์ง€๊ณ  ์ฝ”๋“œ๊ฐ€ ์ง€์ €๋ถ„ํ•จ

Bead.vb

    Public Class Bead
    
    	Sub New(ByVal color1 As Integer, ByVal color2 As Integer)
    		_color1 = color1
    		_color2 = color2
    	End Sub
    
    	Function IsThereColor(ByVal color As Integer) As Boolean
    		If color = Color1 Or color = Color2 Then
    			Return True
    		Else
    			Return False
    		End If
    	End Function
    
    	Function IsMonoColor() As Boolean
    		Return (Color1 = Color2)
    	End Function
    
    	Sub ReverseColor()
    		Dim temp As Integer = Color1
    		_color1 = Color2
    		_color2 = temp
    	End Sub
    
    	Private _color1 As Integer
    	Private _color2 As Integer
    
    	ReadOnly Property Color1() As Integer
    		Get
    			Return _color1
    		End Get
    	End Property
    
    	ReadOnly Property Color2() As Integer
    		Get
    			Return _color2
    		End Get
    	End Property
    
    End Class

Necklace.vb

    Public Class Necklace
    
    	Private _isReparable As Boolean
    	ReadOnly Property IsReparable() As Boolean
    		Get
    			Return _isReparable
    		End Get
    	End Property
    
    	Function AreCountOfColorEven(ByVal beads As List(Of Bead)) As Boolean
    		Dim colorCount(50) As Integer
    
    		For color As Integer = 1 To 50
    			For Each aBead As Bead In beads
    				If aBead.Color1 = color Then colorCount(color) += 1
    				If aBead.Color2 = color Then colorCount(color) += 1
    			Next
    		Next
    
    		For i As Integer = 1 To 50
    			If colorCount(i) Mod 2 <> 0 Then Return False
    		Next
    
    		Return True
    	End Function
    
    	Private _repaired As List(Of Bead) = New List(Of Bead)
    
    	Function GetRepaired() As List(Of Bead)
    		Return _repaired
    	End Function
    
    	Sub TryRepair(ByVal beadList As List(Of Bead))
    		_repaired.Clear()
    
    		If Not AreCountOfColorEven(beadList) Then
    			_isReparable = False
    			Return
    		End If
    
    		Dim beads As List(Of Bead) = GetCopied(beadList)
    		Dim monos As List(Of Bead) = GetAndRemoveMono(beads)
    
    		Dim areAllMono As Boolean = (monos.Count = beadList.Count)
    		If areAllMono Then
    			_isReparable = True
    			_repaired.InsertRange(0, monos)
    			Return
    		End If
    
    		Dim startColor As Integer = beads(0).Color1
    
    		Dim color As Integer = startColor
    		While beads.Count > 0
    			Dim aBead As Bead = GetMatched(color, beads)
    			If aBead.Color2 = color Then aBead.ReverseColor()
    			_repaired.Add(aBead)
    			beads.Remove(aBead)
    			color = aBead.Color2
    			If color = startColor Then Exit While
    		End While
    
    		For Each mono As Bead In monos
    			Dim i As Integer = 0
    			While True
    				If i >= _repaired.Count Then Exit While
    				If _repaired(i).Color2 = mono.Color1 And Not _repaired(i).IsMonoColor() Then
    					_repaired.Insert(i + 1, mono)
    					i += 1
    				End If
    				i += 1
    			End While
    		Next
    
    		_isReparable = True
    		If _repaired.Count <> beadList.Count Then _isReparable = False
    		If _repaired(0).Color1 <> _repaired(_repaired.Count - 1).Color2 Then _isReparable = False
    		For i As Integer = 0 To _repaired.Count - 2
    			If _repaired(i).Color2 <> _repaired(i + 1).Color1 Then _isReparable = False
    		Next
    	End Sub
    
    	Function GetAndRemoveMono(ByVal beads As List(Of Bead)) As List(Of Bead)
    		Dim monos As List(Of Bead) = New List(Of Bead)
    
    		Dim i As Integer = 0
    		While True
    			If i >= beads.Count Then Exit While
    			If beads(i).IsMonoColor() Then
    				monos.Add(beads(i))
    				beads.RemoveAt(i)
    			Else
    				i += 1
    			End If
    		End While
    
    		Return monos
    	End Function
    
    	Shared Function GetCopied(ByVal beadList As List(Of Bead)) As List(Of Bead)
    		Dim beadArray(beadList.Count - 1) As Bead
    		beadList.CopyTo(beadArray)
    		Return New List(Of Bead)(beadArray)
    	End Function
    
    	Function GetMatched(ByVal color As Integer, ByVal beads As List(Of Bead)) As Bead
    		For Each aBead As Bead In beads
    			If aBead.IsThereColor(color) Then Return aBead
    		Next
    		Return Nothing
    	End Function
    
    End Class

!NecklaceTest.vb

    <TestClass()> _
    Public Class NecklaceTest
    
    	<TestMethod()> _
    	Public Sub AreCountOfColorEvenTest()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(1, 2))
    		beads.Add(New Bead(2, 2))
    		beads.Add(New Bead(2, 3))
    		beads.Add(New Bead(3, 1))
    
    		Dim aNecklace As Necklace = New Necklace
    		Assert.IsTrue(aNecklace.AreCountOfColorEven(beads))
    
    		beads.Add(New Bead(3, 4))
    		Assert.IsFalse(aNecklace.AreCountOfColorEven(beads))
    	End Sub
    
    	<TestMethod()> _
    	Public Sub GetCopiedTest()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(1, 2))
    		beads.Add(New Bead(2, 3))
    
    		Dim copied As List(Of Bead) = Necklace.GetCopied(beads)
    		Assert.AreEqual(beads.Count, copied.Count)
    		Assert.AreEqual(beads(0).Color1, copied(0).Color1)
    		Assert.AreEqual(beads(1).Color1, copied(1).Color1)
    	End Sub
    
    	<TestMethod()> _
    	Public Sub GetAndRemoveMonoTest()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(1, 2))
    		beads.Add(New Bead(2, 2))
    		beads.Add(New Bead(2, 2))
    
    		Dim aNecklace As Necklace = New Necklace
    		Dim monos As List(Of Bead) = aNecklace.GetAndRemoveMono(beads)
    		Assert.AreEqual(2, monos.Count)
    	End Sub
    
    	<TestMethod()> _
    	Public Sub GetRepairedTest()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(2, 1))
    		beads.Add(New Bead(2, 2))
    		beads.Add(New Bead(2, 2))
    		beads.Add(New Bead(3, 4))
    		beads.Add(New Bead(3, 1))
    		beads.Add(New Bead(2, 4))
    		beads.Add(New Bead(3, 3))
    
    		Dim aNecklace As Necklace = New Necklace
    		aNecklace.TryRepair(beads)
    		Dim repaired As List(Of Bead) = aNecklace.GetRepaired()
    
    		Assert.IsTrue(aNecklace.IsReparable)
    		Assert.AreEqual(beads.Count, repaired.Count)
    		Assert.AreEqual(repaired(0).Color1, repaired(repaired.Count - 1).Color2)
    		For i As Integer = 1 To repaired.Count - 1
    			Assert.AreEqual(repaired(i - 1).Color2, repaired(i).Color1)
    		Next
    	End Sub
    
    	<TestMethod()> _
    	Public Sub GetRepairedTestTwoCircle()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(2, 1))
    		beads.Add(New Bead(1, 2))
    		beads.Add(New Bead(5, 6))
    		beads.Add(New Bead(5, 6))
    
    		Dim aNecklace As Necklace = New Necklace
    		aNecklace.TryRepair(beads)
    		Assert.IsFalse(aNecklace.IsReparable)
    	End Sub
    
    	<TestMethod()> _
    	Public Sub GetRepairedTestAllMono()
    		Dim beads As List(Of Bead) = New List(Of Bead)
    		beads.Add(New Bead(1, 1))
    		beads.Add(New Bead(1, 1))
    		beads.Add(New Bead(1, 1))
    		beads.Add(New Bead(1, 1))
    
    		Dim aNecklace As Necklace = New Necklace
    		aNecklace.TryRepair(beads)
    		Assert.IsTrue(aNecklace.IsReparable)
    	End Sub
    
    End Class

Outbreak

๋ฌธ์ œ ์š”์•ฝ

  • ์ธ์ ‘ํ•œ ๊ตฌ์Šฌ๊ณผ ๊ฐ™์€ ๋ฐ˜์ชฝ ์ƒ‰๊น”์„ ๊ฐ–๋Š” ๋ชฉ๊ฑธ์ด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฌธ์ œ!

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

  • ๋ฌดํ•œ BFS ์‹œ๋„
    • ์—ญ์‹œ ์˜ˆ์ƒ๋Œ€๋กœ Time Limit..

์†Œ๊ฐ ไธญ

  • Solved ๋ฐ›๊ณ  ์‹ถ์–ด์š”~~!
โš ๏ธ **GitHub.com Fallback** โš ๏ธ