'알고리즘 트레이닝'에 해당되는 글 3건

  1. 2008/06/15 귀차니스트 Algorithm Traning Book - 다섯번째 문제
  2. 2008/06/10 귀차니스트 Algorithm Traning Book - 세 번째 문제
  3. 2008/06/09 귀차니스트 Algorithm Traning Book - 두 번째 문제

Algorithm Traning Book - 다섯번째 문제

Algorithm 2008/06/15 23:13 귀차니스트

  음 한 주가 지나가고 새로운 한 주가 시작되는 시점입니다. 뭐 이런저런 일들이 저번 주에는 많았군요. 어떻게 하다보니 필요에 의한 근무지를 경산으로 잠시 옮기게 되었습니다. 기간은 약 1달 정도로 잡고 있구요. 미완된 프로그램을 완전하게 작성하는 부분이 남았습니다. 야근이 계속 된다면 포스팅이 더뎌 질 수도 있겠군요^^.

  이번 문제도 쉬운 문제입니다. 이름은 Graphical Editor이구요. 입력되는 명령을 파싱하여 구분별로 입력받은 좌표와 데이터로 간단한 데이터 조작하는 것이 문제 해결의 전부입니다. 어떻게 입력을 받고 출력을 해야 하는지 한 번 살펴보도록 하겠습니다.

입력( 제한 X와 Y 좌표는 1 <= X,Y <= 250 까지만 입력됩니다. )
I 5 6
L 2 3 A
S one.bmp
G 2 3 J
F 3 3 J
V 2 3 4 W
H 3 4 2 Z
S two.bmp
X

출력
one.bmp
OOOOO
OOOOO
OAOOO
OOOOO
OOOOO
OOOOO
two.bmp
JJJJJ
JJZZJ
JWJJJ
JWJJJ
JJJJJ
JJJJJ


  대충 이런 출력형식을 띄게 됩니다. 물론 입력값에 대한 정의는 아래와 같죠.

I M N - 모든 픽셀이 M X N 이미지 크기로 됩니다. 데이터는 O로 채워집니다.
C      - 모든 픽셀을 O로 채워 지웁니다.

L X Y C - (X, Y) 픽셀을 C색으로 채웁니다.
V X Y1 Y2 C - X열에 해당하는 Y1에서 Y2까지 C색으로 세로선을 그립니다.
H X1 X2 Y C - Y행에 해당하는 X1에서 X2까지 C색으로 가로선을 그립니다.
K X1 Y1 X2 Y2 C - (X1,Y1)에서 (X2, Y2) 까지 사각형을 C색으로 칠합니다.
F X Y C - (X, Y)에 해당하는 픽셀에 인접하는 같은 색의 모든 픽셀을 C색으로 칠합니다.
S Name - 파일 이름을 출력합니다.
X - 프로그램을 종료합니다.


  정의는 그렇게 어렵지 않죠^^. 그래도 나름 한 가지 생각해볼 것이라면 F 커맨드가 이 중엔 제일 이겠군요. 그래도 별로 어렵지는 않으니 ^^. 재미있게 대충대충 ㅎㅎ

Graphical.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <string>
  3. #include <deque>
  4. int Width, Height;
  5. char Image[251][251];
  6. void StringTokenizer( const std::string &Str, std::deque< std::string > &Token, const std::string &Delimiter );
  7. void NewImage( std::deque< std::string > &Token );
  8. void ClearImage( std::deque< std::string > &Token );
  9. void SetPixel( std::deque< std::string > &Token );
  10. void VerticalLine( std::deque< std::string > &Token );
  11. void HorizonLine( std::deque< std::string > &Token );
  12. void Square( std::deque< std::string > &Token );
  13. void MagicWord( std::deque< std::string > &Token );
  14. void SaveImage( std::deque< std::string > &Token );
  15. void ExitProgram( std::deque< std::string > &Token );
  16. void NearstFill( int X, int Y, char Color, char OldColor );
  17. int main( int argc, char **argv )
  18. {
  19.     char InputString[ 256 ];
  20.     while( true )   {
  21.         std::cin.getline( InputString, 255 );
  22.         std::deque< std::string > TokenContainer;
  23.         StringTokenizer( InputString, TokenContainer, "\t " );
  24.         std::string &Cmd = TokenContainer.front();
  25.         if( Cmd == "I" )
  26.             NewImage( TokenContainer );
  27.         else if( Cmd == "C" )
  28.             ClearImage( TokenContainer );
  29.         else if( Cmd == "L" )
  30.             SetPixel( TokenContainer );
  31.         else if( Cmd == "V" )
  32.             VerticalLine( TokenContainer );
  33.         else if( Cmd == "H" )
  34.             HorizonLine( TokenContainer );
  35.         else if( Cmd == "K" )
  36.             Square( TokenContainer );
  37.         else if( Cmd == "F" )
  38.             MagicWord( TokenContainer );
  39.         else if( Cmd == "S" )
  40.             SaveImage( TokenContainer );
  41.         else if( Cmd == "X" )
  42.             ExitProgram( TokenContainer );
  43.     }
  44.     return 0;
  45. }
  46. void StringTokenizer( const std::string &Str, std::deque< std::string > &Token, const std::string &Delimiter )
  47. {
  48.     std::string::size_type LastPos = Str.find_first_not_of( Delimiter, 0 );
  49.     std::string::size_type Pos     = Str.find_first_of( Delimiter, LastPos );
  50.     while( std::string::npos != Pos || std::string::npos != LastPos )
  51.     {
  52.         Token.push_back( Str.substr( LastPos, Pos - LastPos ) );
  53.         LastPos = Str.find_first_not_of( Delimiter, Pos );
  54.         Pos = Str.find_first_of( Delimiter, LastPos );
  55.     }
  56. }
  57. void NewImage( std::deque< std::string > &Token )
  58. {
  59.     Width = atoi(Token[1].c_str());
  60.     Height = atoi(Token[2].c_str());
  61.     ClearImage( Token );
  62. }
  63. void ClearImage( std::deque< std::string > &Token )
  64. {
  65.     for( int i = 0; i <= Height; ++i )
  66.         for( int j = 0; j <= Width; ++j )
  67.             Image[ i ][ j ] = 'O';
  68. }
  69. void SetPixel( std::deque< std::string > &Token )
  70. {
  71.     int X = atoi(Token[1].c_str());
  72.     int Y = atoi(Token[2].c_str());
  73.     char Color = *Token[3].c_str();
  74.     Image[ Y ][ X ] = Color;
  75. }
  76. void VerticalLine( std::deque< std::string > &Token )
  77. {
  78.     int X = atoi(Token[1].c_str());
  79.     int Y = atoi(Token[2].c_str());
  80.     int Y2 = atoi(Token[3].c_str());
  81.     char Color = *Token[4].c_str();
  82.     if( Y2 < Y )
  83.         std::swap( Y, Y2 );
  84.     for( int i = Y; i <= Y2; ++i )
  85.         Image[ i ][ X ] = Color;
  86. }
  87. void HorizonLine( std::deque< std::string > &Token )
  88. {
  89.     int X = atoi(Token[1].c_str());
  90.     int X2 = atoi(Token[2].c_str());
  91.     int Y = atoi(Token[3].c_str());
  92.     char Color = *Token[4].c_str();
  93.     if( X2 < X )
  94.         std::swap( X, X2 );
  95.     for( int i = X; i <= X2; ++i )
  96.         Image[ Y ][ i ] = Color;
  97. }
  98. void Square( std::deque< std::string > &Token )
  99. {
  100.     int X = atoi(Token[1].c_str());
  101.     int X2 = atoi(Token[2].c_str());
  102.     int Y = atoi(Token[3].c_str());
  103.     int Y2 = atoi(Token[4].c_str());
  104.     char Color = *Token[4].c_str();
  105.     if( X2 < X )
  106.         std::swap( X, X2 );
  107.     if( Y2 < 2 )
  108.         std::swap( Y, Y2 );
  109.     for( int i = Y; i <= Y2; ++i )
  110.         for( int j = X; j <= X2; ++j )
  111.             Image[ i ][ j ] = Color;
  112. }
  113. void MagicWord( std::deque< std::string > &Token )
  114. {
  115.     int X = atoi(Token[1].c_str());
  116.     int Y = atoi(Token[2].c_str());
  117.     char Color = *Token[3].c_str();
  118.     char OldColor = Image[ Y ][ X ];
  119.     NearstFill( X, Y, Color, OldColor );
  120. }
  121. void SaveImage( std::deque< std::string > &Token )
  122. {
  123.     std::cout << Token[1] << std::endl;
  124.     for( int i = 1; i <= Height; ++i )  {
  125.         for( int j = 1; j <= Width; ++j )
  126.             std::cout << Image[ i ][ j ];
  127.         std::cout << std::endl;
  128.     }
  129. }
  130. void ExitProgram( std::deque< std::string > &Token )
  131. {
  132.     exit(0);
  133. }
  134. void NearstFill( int X, int Y, char Color, char OldColor )
  135. {
  136.     if( Image[ Y ][ X ] == OldColor )   {
  137.         Image[ Y ][ X ] = Color;
  138.         if( X > 1 )
  139.             NearstFill( X - 1, Y, Color, OldColor );
  140.         if( X < Width )
  141.             NearstFill( X + 1, Y, Color, OldColor );
  142.         if( Y > 1 )
  143.             NearstFill( X, Y - 1, Color, OldColor );
  144.         if( Y < Height )
  145.             NearstFill( X, Y + 1, Color, OldColor );
  146.     }
  147. }

  깔끔하게 해보려고 했지만 일단 그냥 푸는게 더 좋을것 같아서 대충대충 했습니다. 일단 결과물이 나와야 과정이 중요하지 않겠습니까^^? 그럼 새로운 한 주 잘보세요.

크리에이티브 커먼즈 라이센스
Creative Commons License

"Algorithm" 분류의 다른 글

Dovelet - (1) (0)2010/03/13
Algorithm Traning Book - 세 번째 문제 (0)2008/06/10
Algorithm Traning Book - 두 번째 문제 (0)2008/06/09
2008/06/15 23:13 2008/06/15 23:13

댓글을 달아 주세요

Algorithm Traning Book - 세 번째 문제

Algorithm 2008/06/10 23:42 귀차니스트

  금방 풀어봤던 한 문제는 The Trip(여행)이라는 문제입니다. 이 것도 초반 문제다 보니 별로 어렵지는 않네요. 대략적인 문제의 개요는 여행을 가는데 여러명이 사용하는 경비를 각자 내려니 너무 귀찮다는거죠. 그리하여 각 사람마다 여행경비, 숙박비 등을 지불하게 되는데 이게 또 그냥 넘어가면 껄쩍지근 하잖습니까?^^ 그래서 돈을 나중에 서로 교환을 하여 서로 지불액수를 맞추게 됩니다.
  여기서 포인트는 액수를 맞추기 위하여 이동하는 돈의 개수를 센트까지 세어라 입니다. 물론 입력은 달러 단위로 받게 되구요. 일단 입력과 출력 예제를 보겠습니다.

입력:
3
10.00
20.00
30.00
4
15.00
15.01
3.00
3.01

출력:
$10.00
$11.99


TheTrip.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <cmath>
  3. int main(int argc, char **argv)
  4. {
  5.     int CntInput = 0;
  6.     double CostList[1000] = {0.00,};
  7.     do{
  8.         double Average = 0.00;
  9.         double MoveCost = 0.00;
  10.         std::cin >> CntInput;
  11.         for( int i = 0; i < CntInput; ++i ) {
  12.             std::cin >> CostList[i];
  13.             Average += CostList[i];
  14.         }
  15.         if( CntInput != 0 ) {
  16.             Average /= static_cast<double>(CntInput);
  17.             double DiffCost = 0.00;
  18.             for( int i = 0; i < CntInput; ++i ) {
  19.                 DiffCost = Average - CostList[i];
  20.                 MoveCost += ( DiffCost > 0.00 ? DiffCost : 0.00 );
  21.             }
  22.             std::cout.precision(2);
  23.             std::cout << std::fixed << '$' << std::floor(MoveCost * 100) / 100 << std::endl;
  24.         }
  25.     }while( CntInput != 0 );
  26.     return 0;
  27. }

  이 문제도 사실 어렵지 않기 때문에 대충대충 해서 풀었습니다. 한 가지 숫자의 정밀도 출력으로 인해서 11.99가 출력되어야할 시점에 12가 출력될 수 있기 떄문에 센트까지만 이라는 힌트를 참조하여 * 100을 한 다음 / 100을 하여 내림을 시켜버리면 문제없이 출력이 됩니다.
  다음 문제도 계속 풀어봐야 겠군요^^.

크리에이티브 커먼즈 라이센스
Creative Commons License

"Algorithm" 분류의 다른 글

Dovelet - (1) (0)2010/03/13
Algorithm Traning Book - 다섯번째 문제 (0)2008/06/15
Algorithm Traning Book - 두 번째 문제 (0)2008/06/09
2008/06/10 23:42 2008/06/10 23:42

댓글을 달아 주세요

Algorithm Traning Book - 두 번째 문제

Algorithm 2008/06/09 23:29 귀차니스트

  음 뭐 책을 사놓고 도통 보지 않는 것 같아 오늘 야근 하고 돌아온 김에 잠시 봤는데 시간이 없어 많은 것을 생각하는 문제는 선택하지 못하고 아주 간단한 문제를 선택해봤습니다. 아무래도 첫 술부터 배부를 수는 없듯이 차근차근 있는 문제 그냥 연습한다 치고 하나씩 풀어보기로 했습니다.
  문제의 이름은 Mine Sweeper네요. 대충 입력, 출력의 예와 코드 는 다음과 같습니다.

입력

4 4
*...
....
.*..
....

출력
*100
2210
1*10
1110


MineSweeper.cpp (Language : cpp)
  1. #include <iostream>
  2. int Width, Height;
  3. char MineField[100][100];
  4. int GetField(int col, int row)
  5. {
  6.     if( (0 <= col && col < Height) &&
  7.         (0 <= row && row < Width )) {
  8.         return (MineField[col][row] == '*' ? 1 : 0);
  9.     }
  10.     return 0;
  11. }
  12. char Calculate(int col, int row)
  13. {
  14.     if( GetField(col, row) )
  15.         return '*';
  16.     int Count = 0;
  17.     Count += GetField( col - 1, row - 1 );
  18.     Count += GetField( col - 1, row );
  19.     Count += GetField( col - 1, row + 1 );
  20.     Count += GetField( col, row - 1 );
  21.     Count += GetField( col, row + 1 );
  22.     Count += GetField( col + 1, row - 1 );
  23.     Count += GetField( col + 1, row );
  24.     Count += GetField( col + 1, row + 1 );
  25.     return '0' + Count;
  26. }
  27. int main( int argc, char **argv )
  28. {
  29.     while( true )   {
  30.         std::cin >> Width >> Height;
  31.         if( Width == 0 && Height == 0 )
  32.             break;
  33.         for( int i = 0; i < Height; ++i )   {
  34.             for( int j = 0; j < Width; ++j )    {
  35.                 std::cin >> MineField[i][j];
  36.             }
  37.         }
  38.         for( int i = 0; i < Height; ++i )   {
  39.             for( int j = 0; j < Width; ++j )    {
  40.                 std::cout << Calculate(i, j);
  41.             }
  42.             std::cout << std::endl;
  43.         }
  44.     }
  45.     return 0;
  46. }


  복잡한 문제는 아니죠^^? 그냥 아주 간단하길래 대충 생각하고 대충 풀었습니다. 코드가 즈질 이군요 ㅎㅎ
계속해서 한 문제씩 차근차근 풀어봐야 겠습니다.

크리에이티브 커먼즈 라이센스
Creative Commons License

"Algorithm" 분류의 다른 글

Dovelet - (1) (0)2010/03/13
Algorithm Traning Book - 다섯번째 문제 (0)2008/06/15
Algorithm Traning Book - 세 번째 문제 (0)2008/06/10
2008/06/09 23:29 2008/06/09 23:29

댓글을 달아 주세요