algorithm wheres waldort - andstudy/forge GitHub Wiki

ParkPD

  • toupper ์—๋Ÿฌ ์ฐธ๊ณ ๋‚ด์šฉ
  • ํ•˜๋‚˜ ๋”
  • Presentation ์—๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.
    • ๋‘ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‚ฌ์ด์—์„œ๋งŒ ๊ฐœํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œํ›„ ๊ฐœํ–‰์ด ์žˆ์œผ๋ฉด PE๊ฐ€ ๋‚ฉ๋‹ˆ๋‹ค. /* @JUDGE_ID:parkpd 10038 C "test" */

      /* @BEGIN_OF_SOURCE_CODE */
      
      #include <iostream>
      #include <vector>
      #include <set>
      #include <string>
      #include <strstream>
      #include <algorithm>
      
      using namespace std;
      
      bool IsInRange(int value, int from, int to)
      {
      	return (from <= value) && (value <= to);
      }
      
      //#define _UNIT_TEST
      
      #ifdef _UNIT_TEST
      
      #include "../UnitTest++/src/UnitTest++.h"
      
      int main()
      {
      	UnitTest::RunAllTests();
      
      	char temp;
      	cin >> temp;
      
      	return 0;
      }
      
      #endif
      
      // code implement
      
      class CWordGrid
      {
      public:
      	static bool ConsoleTest(istream& input, ostream& output);
      
      	CWordGrid() : m_Row(0), m_Col(0) {}
      
      	void Init(int row, int col);
      	void InputData(int row, string data);
      	bool FindString(string str, int& row, int& col);
      	bool Find(const string& str, int row, int col);
      	bool IsSame(int row, int col, char c);
      
      	int m_Row;
      	int m_Col;
      	char m_Data[51][51];	//
      };
      
      void CWordGrid::Init(int row, int col)
      {
      	m_Row = row;
      	m_Col = col;
      }
      
      void CWordGrid::InputData(int row, string data)
      {
      	// ์ „๋ถ€ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พผ๋‹ค.
      	transform(
      		data.begin(), data.end(), 
      		data.begin(),
      		//toupper);		// gcc ์—์„œ ์ด๊ฑฐ ์—๋Ÿฌ๋‚จ. -.-;;
      		(int(*)(int)) toupper);
      
      	//strcpy_s(m_Data[row], data.c_str());
      	strcpy(m_Data[row], data.c_str());
      }
      
      bool CWordGrid::FindString(string str, int& row, int& col)
      {
      	transform(
      		str.begin(), str.end(), 
      		str.begin(),
      		//toupper);
      		(int(*)(int)) toupper);
      
      	for (int r = 0; r < m_Row; ++r)
      	{
      		for (int c = 0; c < m_Col; ++c)
      		{
      			if (Find(str, r, c))
      			{
      				row = r;
      				col = c;
      				return true;
      			}
      		}
      	}
      
      	return false;
      }
      
      namespace
      {
      	// <- ๋ถ€ํ„ฐ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™
      	const int Directions[8][2] = 
      	{
      		{-1,  0},	// <-
      		{-1, -1},
      		{ 0, -1},	// ์œ„๋กœ
      		{ 1,  1},
      		{ 1,  0},	// ->
      		{ 1,  1},
      		{ 0,  1},	// ์•„๋ž˜๋กœ
      		{-1,  1}
      	};
      }
      
      bool CWordGrid::Find(const string& str, int row, int col)
      {
      	if (m_Data[row][col] != str[0])
      	{
      		return false;
      	}
      
      	const int length = (int)str.length();
      
      	// 8 ๋ฐฉํ–ฅ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ธฐ
      	for (int i = 0; i < 8; ++i)
      	{
      		bool found = true;
      		int r = row;
      		int c = col;
      
      		for (int j = 1; j < length; ++j)
      		{
      			r += Directions[i][0];
      			c += Directions[i][1];
      			if (!IsSame(r, c, str[j]))
      			{
      				found = false;
      				break;
      			}
      		}
      
      		if (found)
      		{
      			return true;
      		}
      	}
      
      	return false;
      }
      
      bool CWordGrid::IsSame(int row, int col, char c)
      {
      	if (!IsInRange(row, 0, m_Row - 1) || !IsInRange(col, 0, m_Col - 1))
      	{
      		return false;
      	}
      
      	return c == m_Data[row][col];
      }
      
      bool CWordGrid::ConsoleTest(istream& input, ostream& output)
      {
      	int num = 0;
      	if (!(input >> num))
      	{
      		return false;
      	}
      
      	// ์—ฐ์‚ฐ์ž ์šฐ์„ ์ˆœ์œ„ ์ฃผ์˜
      	if (num <= 0)
      	{
      		return false;
      	}
      
      	string inputString;
      	int row;
      	int col;
      
      	for (int i = 0; i < num; ++i)
      	{
      		CWordGrid grid;
      
      		input >> row >> col;
      		grid.Init(row, col);
      
      		getline(input, inputString);
      
      		for (int r = 0; r < row; ++r)
      		{
      			getline(input, inputString);
      			grid.InputData(r, inputString);
      		}
      
      		int inputNum = 0;
      		input >> inputNum;
      
      		getline(input, inputString);
      
      		int rowOut = 0;
      		int colOut = 0;
      		for (int i = 0; i < inputNum; ++i)
      		{
      			getline(input, inputString);
      			grid.FindString(inputString, rowOut, colOut);
      			output << rowOut + 1 << ' ' << colOut + 1 << '\n';
      		}
      
      		output << '\n';
      	}
      
      	return true;
      }
      
      #ifndef _UNIT_TEST
      
      int main()
      {
      	CWordGrid::ConsoleTest(cin, cout);
      
      	return 0;
      }
      
      #else
      
      // tests
      
      struct FixtureWordGrid : public CWordGrid
      {
      	int row;
      	int col;
      
      	stringstream testCin;
      	stringstream testCout;
      };
      
      TEST_FIXTURE(FixtureWordGrid, InputData)
      {
      	string data1 = "123";
      	string data2 = "567";
      	InputData(0, data1);
      	InputData(1, data2);
      	InputData(1, data1);
      }
      
      TEST_FIXTURE(FixtureWordGrid, FindString)
      {
      	CHECK(!FindString("hi", row, col));
      }
      
      struct FixtureSetupWordGrid : public FixtureWordGrid
      {
      	FixtureSetupWordGrid()
      	{
      		Init(2, 2);
      		InputData(0, "hi");
      		InputData(1, "ab");
      	}
      };
      
      TEST_FIXTURE(FixtureSetupWordGrid, IsSame)
      {
      	CHECK(IsSame(0, 0, 'H'));
      	CHECK(IsSame(0, 1, 'I'));
      	CHECK(!IsSame(1, 0, 'H'));
      	CHECK(!IsSame(1, 1, 'H'));
      
      	// ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋…€์„๋“ค๋„ false ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.
      	CHECK(!IsSame(-1, -1, 'H'));
      	CHECK(!IsSame(5, 3, 'H'));
      }
      
      TEST_FIXTURE(FixtureSetupWordGrid, FindString)
      {
      	CHECK(Find("HI", 0, 0));
      }
      
      TEST_FIXTURE(FixtureWordGrid, ConsoleTest)
      {
      	string input =
      		"1\n\n"
      		"8 11\n"
      		"abcDEFGhigg\n"
      		"hEbkWalDork\n"
      		"FtyAwaldORm\n"
      		"FtsimrLqsrc\n"
      		"byoArBeDeyv\n"
      		"Klcbqwikomk\n"
      		"strEBGadhrb\n"
      		"yUiqlxcnBjf\n"
      		"4\n"
      		"Waldorf\n"
      		"Bambi\n"
      		"Betty\n"
      		"Dagbert";
      
      	testCin << input;
      	CWordGrid::ConsoleTest(testCin, testCout);
      	
      	CHECK_EQUAL("2 5\n2 3\n1 2\n7 8\n", testCout.str());
      };
      
      #endif
      
      /* @END_OF_SOURCE_CODE */
      

kukuman

  • Runtime Error๋‚˜๋„ค์šฉ ใ…‹ ๋ฐ๋ชจ

  • Searcher.java

      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.util.ArrayList;
      
      
      public class Searcher {
      	
      	private char [][] crossSource;
      	
      	public Searcher(String[] sourceLine,int height,int width) {
      		initCrossSrouce(sourceLine,height,width);
      	}
      
      	private void initCrossSrouce(String[] sourceLines,int height,int width) {
      		crossSource = new char[height][width];
      		for(int i=0;i<sourceLines.length;i++){
      			String curLine = sourceLines[i];
      			for(int j=0;j<curLine.length();j++){
      				crossSource[i][j] = curLine.charAt(j);
      			}
      		}
      	}
      
      	public boolean isStartWith(String source, String match) {
      		source = source.toLowerCase();
      		match = match.toLowerCase();
      		return source.startsWith(match);
      	}
      
      	public String devideTop(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y;i>=0;i--){
      			builder.append(crossSource[i][x]);
      		}
      		
      		return builder.toString().toLowerCase();
      	}
      	
      	public int getWidth(){
      		if(crossSource.length < 1){
      			return 0;
      		}
      		return crossSource[0].length;
      	}
      	
      	public int getHeight(){
      		return crossSource.length;
      	}
      
      	public String devideDown(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y;i<getHeight();i++){
      			builder.append(crossSource[i][x]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public String devideLeft(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=x;i>=0;i--){
      			builder.append(crossSource[y][i]);
      		}
      		return builder.toString().toLowerCase();
      	}
      	public String devideRight(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=x;i<getWidth();i++){
      			builder.append(crossSource[y][i]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public String devideUpLeft(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y,j=x;i>=0 && j>=0;i--,j--){
      				builder.append(crossSource[i][j]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public String devideUpRight(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y,j=x;i>=0 && j<getWidth();i--,j++){
      			builder.append(crossSource[i][j]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public String devideDownLeft(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y,j=x;i<getHeight() && j>=0;i++,j--){
      			builder.append(crossSource[i][j]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public String devideDownRight(int y, int x) {
      		StringBuilder builder = new StringBuilder();
      		for(int i=y,j=x;i<getHeight() && j<getWidth();i++,j++){
      			builder.append(crossSource[i][j]);
      		}
      		return builder.toString().toLowerCase();
      	}
      
      	public Point searchString(String match) {
      		for(int i=0;i<getWidth();i++){
      			for(int j=0; j<getHeight();j++){
      				if(isStartWith(devideTop(i, j), match) 
      					|| isStartWith(devideDown(i, j), match)
      					|| isStartWith(devideLeft(i, j), match)
      					|| isStartWith(devideRight(i, j), match)
      					|| isStartWith(devideUpLeft(i, j), match)
      					|| isStartWith(devideUpRight(i, j), match)
      					|| isStartWith(devideDownLeft(i, j), match)
      					|| isStartWith(devideDownRight(i, j), match) ){
      					return new Point(i+1,j+1);
      				}
      			}
      		}
      		return null;
      	}
      	
      	
      	public static void main(String[] args) throws NumberFormatException, IOException {
      		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      		int cases = Integer.parseInt(reader.readLine().trim());
      		ArrayList<String> results = new ArrayList<String>();
      		for(int i=0;i<cases;i++){
      			reader.readLine();
      			String line = reader.readLine();
      			String[] split = line.split(" ");
      			int height = Integer.parseInt(split[0]);
      			int width = Integer.parseInt(split[1]);
      			String [] lines = new String[height];
      			for(int j=0;j<height;j++){
      				lines[j] = reader.readLine();
      			}
      			
      			int numToFind = Integer.parseInt(reader.readLine().trim());
      			Searcher searcher = new Searcher(lines,height,width);
      			for(int j=0;j<numToFind;j++){
      				Point result  = searcher.searchString(reader.readLine().trim());
      				results.add(result.toString());
      			}
      			results.add("");
      		}
      		
      		for(String line : results){
      			System.out.println(line);
      		}
      	}
      }
    
  • Point.java

      public class Point {
      	@Override
      	public boolean equals(Object obj) {
      		if (obj instanceof Point) {
      			Point pnt = (Point) obj;
      			return this.x == pnt.getX() && this.y == pnt.getY();
      		}else{
      			return false;
      		}
      	}
      
      	private int x;
      	private int y;
      	
      	public Point(int y , int x){
      		this.x = x;
      		this.y = y;
      	}
      	
      	public String toString(){
      		return y+" "+x;
      	}
      
      	public int getX() {
      		return x;
      	}
      
      	public int getY() {
      		return y;
      	}
      }
    
  • TestCase

      import junit.framework.TestCase;
      
      
      public class SearcherTest extends TestCase {
      	Searcher searcher ;
      	private String [] crossSource = {
      			"abcDEFGhigg",
      			"hEbkWalDork",
      			"FtyAwaldORm",
      			"FtsimrLqsrc",
      			"byoArBeDeyv",
      			"Klcbqwikomk",
      			"strEBGadhrb",
      			"yUiqlxcnBjf"
      	};
      	@Override
      	protected void setUp() throws Exception {
      		searcher = new Searcher(crossSource,8,11);
      		super.setUp();
      	}
      	public void testLineMatch(){
      		String source = "abcdefg";
      		assertTrue(searcher.isStartWith(source,"abcdef"));
      		assertTrue(searcher.isStartWith(source,"Abcdef"));
      		assertFalse(searcher.isStartWith(source,"bcdefg"));
      		assertFalse(searcher.isStartWith(source,"Bcdefg"));
      	}
      	
      	public void testDevideTop(){
      		
      		assertEquals("akd", searcher.devideTop(2,3));
      		assertEquals("a", searcher.devideTop(0,0));
      		assertEquals("cmkg", searcher.devideTop(3,10));
      	}
      	public void testDevideDown(){
      		assertEquals("ahffbksy", searcher.devideDown(0,0));
      		assertEquals("bl", searcher.devideDown(6,4));
      	}
      	public void testDevideLeft(){
      		assertEquals("eh", searcher.devideLeft(1,1));
      		assertEquals("erts", searcher.devideLeft(6,3));
      	}
      	public void testDevideRight(){
      		assertEquals("ldork", searcher.devideRight(1, 6));
      		assertEquals("jf", searcher.devideRight(7, 9));
      	}
      	public void testDevideUpLeft(){
      		assertEquals("ea", searcher.devideUpLeft(1,1));
      		assertEquals("th", searcher.devideUpLeft(2,1));
      	}
      
      	public void testDevideUpRight(){
      		assertEquals("di", searcher.devideUpRight(1,7));
      		assertEquals("srk", searcher.devideUpRight(3,8));
      		
      	}
      	public void testDevideDownLeft(){
      		assertEquals("ef", searcher.devideDownLeft(1,1));
      		assertEquals("btf", searcher.devideDownLeft(1,2));
      	}
      	public void testDevideDownRight(){
      		assertEquals("irm", searcher.devideDownRight(0,8));
      	}
      	
      	public void testSearchString(){
      		assertEquals(new Point(2,5), searcher.searchString("Waldorf"));
      		assertEquals(new Point(2, 3), searcher.searchString("Bambi"));
      		assertEquals(new Point(1, 2), searcher.searchString("Betty"));
      		assertEquals(new Point(7, 8), searcher.searchString("Dagbert"));
      	}
      }
    

Outbreak

๋ฌธ์ œ ์š”์•ฝ

  • mxn ๊ทธ๋ฆฌ๋“œ์—์„œ ๋ฐฉํ–ฅ์— ์ƒ๊ด€์—†์ด ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด์ด ๋งค์นญ๋˜๋Š” ์ฒซ ์œ„์น˜ ์ฐพ๊ธฐ

๋ฌธ์ œ ํ•ด๊ฒฐ

  • ์ „์ฒด ๊ทธ๋ฆฌ๋“œ์— ๋Œ€ํ•ด์„œ 8๋ฐฉํ–ฅ ๋ฌธ์ž์—ด ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
    • ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ = ํŠน์ • ๋ฐฉํ–ฅ ๋ฌธ์ž์—ด + ๊ฐ ๊ธ€์ž์˜ ์œ„์น˜์ •๋ณด
    • ๋Œ€๊ฐ์„ ์˜ ๊ฒฝ์šฐ ์ง์„ ์˜ ๋ฐฉ์ •์‹ ์ด์šฉํ•ด ๋ฌธ์ž์—ด ์ƒ์„ฑ

๊ธฐํƒ€

  • ์Œ์ฃผ ์ฝ”๋”ฉ ใ„ฑใ„ฑ

๋ฐ์ดํ„ฐ๋ถ€

        class MetaData
        {
            public class Dim
            {
                public int col;
                public int row;
    
                public Dim(int row, int col)
                {
                    this.col = col;
                    this.row = row;
                }
            }
    
            public string data;
            public List<Dim> dimList;
          
            public string Reverse
            {
                get
                { 
                    char[] array = data.ToCharArray();
                    Array.Reverse(array);
                    return new string(array);
                }
            }
    
            public List<Dim> ReverseDimList
            {
                get
                {
                    List<MetaData.Dim> rDim = new List<MetaData.Dim>(dimList);
                    rDim.Reverse();
                    return rDim;
                }
            }
            
            public MetaData(string str, List<Dim> dim)
            {
                this.data = str;
                this.dimList = dim;
            }        
        }

์ฒ˜๋ฆฌ๋ถ€

        class MetaDataProcessor
        {
            public List<MetaData> All = new List<MetaData>();
    
            public MetaDataProcessor(char[][] input)
            {           
                int rowCnt = input.Length;
                int colCnt = input[0].GetLength(0);
    
                // rows
                for (int i = 0; i < rowCnt; i++)
                {
                    string s = string.Empty;
                    List<MetaData.Dim> dim = new List<MetaData.Dim>();
    
                    for (int j = 0; j < colCnt; j++)
                    {
                        s += input[i][j];
                        dim.Add(new MetaData.Dim(i,j));
                    }
    
                    All.Add(new MetaData(s,dim));
                }
    
                // cols
                for (int i = 0; i < colCnt; i++)
                {
                    string s = string.Empty;
                    List<MetaData.Dim> dim = new List<MetaData.Dim>();
    
                    for (int j = 0; j < rowCnt; j++)
                    {
                        s += input[j][i];
                        dim.Add(new MetaData.Dim(j, i));
                    }
    
                    All.Add(new MetaData(s, dim));
                }
    
                // diagonal
                int X = colCnt;
                int Y = rowCnt;
    
                int minD = 0;
                int maxD = 0;
    
                // diagonal #1
                minD = -colCnt;
                maxD = rowCnt;
                for (int d = minD; d < maxD; d++)
                {
                    string s = string.Empty;
                    List<MetaData.Dim> dim = new List<MetaData.Dim>();
    
                    for (int x = 0; x < X; x++)
                    {
                        int y = x + d;
    
                        if (y >= Y || y < 0)
                            continue;
    
                        s += input[y][x];
                        dim.Add(new MetaData.Dim(y, x));
                    }
    
                    All.Add(new MetaData(s, dim));
                }
    
                // diagonal #2
                minD = 0;
                maxD = X + Y;
                for (int d = minD; d < maxD; d++)
                {
                    string s = string.Empty;
                    List<MetaData.Dim> dim = new List<MetaData.Dim>();
    
                    for (int x = 0; x < X; x++)
                    {
                        int y = -x + d;
    
                        if (y >= Y || y < 0)
                            continue;
    
                        s += input[y][x];
                        dim.Add(new MetaData.Dim(y, x));
                    }
    
                    All.Add(new MetaData(s, dim));
                }
                
                // reverse
                List<MetaData> rAll = new List<MetaData>();
    
                foreach (MetaData d in All)
                {                
                    rAll.Add(new MetaData(d.Reverse, d.ReverseDimList));
                }
    
                All.AddRange(rAll);
    
                Console.WriteLine("์ด ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ : {0}", All.Count);
            }
    
        }

์‹คํ–‰๋ถ€

        class Solver
        {
            public static void Exec()
            {
                Input input = new Input();
    
                MetaDataProcessor processor = new MetaDataProcessor(input.RefinedData);
              
                foreach(string question in input.RawData2)
                {
                    foreach (MetaData d in processor.All)
                    {
                        int result = d.data.ToLower().IndexOf(question.ToLower());
    
                        if (result == -1)
                            continue;
    
                        Console.WriteLine("{0}\t: {1} {2}", 
               question, d.dimList[result].row + 1, d.dimList[result].col + 1);                    
                    }
                }
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Solver.Exec();            
            }
        }
โš ๏ธ **GitHub.com Fallback** โš ๏ธ