일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 독서 감상문
- 정보영재원
- 풀이&소스코드저작권:왕유승
- 배열
- 문제출저:www.dovelet.com
- c언어
- 리눅스
- DBMS
- For문
- C++
- C
- API
- 다중반복문
- 자료구조
- if문
- Backdoor
- 프로그래밍
- 반복문
- 참조은요양병원
- 정보과학
- Linux
- 수학영재원
- 독후감
- 제어문
- 정보올림피아드
- 백도어
- 리눅스 명령어
- 영재교육원
- IT
- 알고리즘
- Today
- Total
되는대로 살자
[C언어 기출문제&풀이] 그래픽 편집기(Graphical Editor) 본문
문제:포토샵 같은 그래픽 편집기를 이용하면 텍스트 편집기에서 문서를 수정하는 것처럼 비트맵 이미지를 수정할 수 있다. 이미지는 픽셀로 이루어진 MXN배열로 표현되며 각 픽셀마다 색이 주어진다.
간단한 대화형 그래픽 편집기 흉내를 낼 수 있는 프로그램을 만들어 보자.
입력:입력은 한 줄에 하나씩의 편집기 명령으로 구성된다. 각 명령은 줄 맨 앞에 있는 대문자 한 개로 표현된다. 매개변수가 필요한 경우에는 그 명령과 같은 줄에 스페이스로 분리되어 매개변수가 입력된다.
픽셀 좌표는 1이상 M이하의 열 번호와 1이상 N이하의 행 번호, 이렇게 두 개의 정수로 표현되며 이때 1<=M,N<=250라는 조건이 만족된다. 표의 왼쪽 위 꼭지점을 원점으로 삼는다. 색은 대문자로 지정된다. 편집기에서 받아들이는 명령은 다음과 같다.
I M N :모든 픽셀이 흰색(O)으로 칠해진MXN 이미지를 새로 만든다.
C: 모든 픽샐을 흰색(O)으로 칠해서 표를 지운다. 이미지의 크기는 바뀌지 않는다.
L X Y C : (X,Y)픽셀을 주어진 색(C)으로 칠한다.
V X Y1 Y2 C : X열에 Y1 행과 Y2행(Y1,Y2포함)사이에 주어진 색(C)으로 수직 방향 직선을 긋는다.
H X1 X2 Y C : Y행에 X1 열과 X2행 (X1,X2 포함) 사이에 주어진 색(C)으로 수평 방향 직선을 긋는다.
K X1 Y1 X2 Y2 C : 주어진 색(C)으로 채워진 직사각형을 그린다. (X1,Y1)은 왼쪽 위 끝점, (X2,Y2)는 오른쪽 아래 끝 점을 의미한다.
F X Y C : R 영역을 주어진 색(C)으로 채우는데, 영역 R은 다음과 같이 정의된다. (X,Y)픽셀과 색이 같고 R에 포함된 픽셀과 맞닿은 부분이 하나라도 있다면 그 픽셀도 R 영역에 포함된다.
S Name : 파일명은 MSDOS 8.3 형식으로 출력하고 그 뒤에 현재 이미지의 내용을 출력한다.
X: 세션을 종료한다.
출력 : S NAME이라는 명령이 있을 때마다 NAME으로 주어진 파일명을 출력하고 현재 이미지의 내용을 출력한다. 각 행은 각 픽셀의 색을 나타내는 문자로 표시된다. 출력 예를 참고하자. I,C,L,V,H,K,F,S,X를 제외한 문자로 정의된 명령이 있으면 그 줄 전체를 무시하고 다음 명령으로 넘어간다. 다른 오류에 대해서는 프로그램의 행동을 예측할 수 없다.
풀이:이 문제는 내가 뿌요뿌요 프로그램을 만들때의 알고리즘과 많이 비슷하기 때문에 예로 인용하도록 하겠다. 이런 X,Y를 사용하는 배열에서 자주하는 실수는 map[y][x]라고 쓰지 않고, map[x][y]라고 쓰는 것이다. 나도 테트리스와 뿌요뿌요를 분석하며 프로그램을 만들 때 디버깅 하면서 가장 멍청했다고 생각한 것이 map[y][x]를 잘못 표기한 것이다. 그리고 왠만한 것은 문제의 조건에 따라 코딩만 잘 하면 된다. 그나마 특별하다고 할 수 있는 것은 F명령인데 이 부분은 상하좌우에 같은 색이 있는지를 판별하고 같은 색이면 자기호출(재귀)을 한다.
아, 그리고 이 문제와 상관없는 일이지만 이 문제를 풀면서 생긴 일이라 적는다. 참고로 지역변수와 같은 이름으로 전역변수를 선언하지 말자..
소스코드 :
#include <stdio.h>
static char bitmap[100][100],color;
static int m=0,n=0;
void Fill(int,int,char,char);
void Fill(int i, int j,char old_c,char color)
{
bitmap[i][j]=color;
if(i > 1 && bitmap[i-1][j] == old_c)
Fill(i-1,j,old_c,color);
if(i < n && bitmap[i+1][j] == old_c)
Fill(i+1,j,old_c,color);
if(j > 1 && bitmap[i][j-1] == old_c)
Fill(i,j-1,old_c,color);
if(j < m && bitmap[i][j+1] == old_c)
Fill(i,j+1,old_c,color);
}
int main()
{
int i,j,i1,i2,j1,j2,temp;
char color,command='\0',name[20];
while(command != 'X')
{
scanf("%c",&command);
switch(command)
{
case 'I':
scanf("%d%d",&m,&n);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
bitmap[i][j]='O';
break;
case 'C':
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
bitmap[i][j]='O';
break;
case 'L':
scanf("%d %d %c",&j,&i,&color);
bitmap[i][j]=color;
break;
case 'V':
scanf("%d %d %d %c",&j,&i1,&i2,&color);
if(i1>i2)
{
temp = i1;
i1=i2;
i2=temp;
}
for(i=i1;i<=i2;i++)
bitmap[i][j]=color;
break;
case 'H':
scanf("%d %d %d %c",&j1,&j2,&i,&color);
if(j1 > j2)
{
temp=j1;
j1=j2;
j2=temp;
}
for(j=j1;j<=j2;j++)
bitmap[i][j]=color;
break;
case 'K':
scanf("%d %d %d %d %c",&j1,&i1,&j2,&i2,&color);
for(i=i1;i<=i2;i++)
for(j=j1;j<=j2;j++)
bitmap[j][i]=color;
break;
case 'F':
scanf("%d %d %c",&j,&i, &color);
Fill(i,j,bitmap[i][j],color);
break;
case 'S':
scanf("%s",&name);
printf("%s\n",name);
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++)
putchar(bitmap[i][j]);
putchar('\n');
}
break;
}
}
}
'2009~2014 > C/C++' 카테고리의 다른 글
list (0) | 2011.05.14 |
---|---|
[C언어 기출문제&풀이] 인터프리터(Interpreter) (0) | 2011.05.14 |
[C언어 기출문제&풀이] LCD 디스플레이 (0) | 2011.05.13 |
[C언어 기출문제&풀이] 여행(the trip) (0) | 2011.05.13 |
[C언어 기출문제&풀이] 지뢰찾기(minesweeper) (0) | 2011.05.13 |