일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- DBMS
- 알고리즘
- 리눅스 명령어
- Linux
- 다중반복문
- c언어
- 영재교육원
- 정보영재원
- 수학영재원
- if문
- Backdoor
- 문제출저:www.dovelet.com
- C
- 배열
- 독서 감상문
- IT
- 프로그래밍
- 리눅스
- 참조은요양병원
- 반복문
- 백도어
- 정보올림피아드
- For문
- 풀이&소스코드저작권:왕유승
- 제어문
- C++
- 정보과학
- API
- 자료구조
- 독후감
- Today
- Total
되는대로 살자
[C언어 기출문제&풀이] 인터프리터(Interpreter) 본문
어떤 컴퓨터에 열 개의 레지스터와 1000워드 분량의 램(RAM)이 있다. 각 레지스터 또는 램 위치에는 0 이상 999 이하의 세자리 정수가 저장된다. 명령어에는 세 자리 정수로 인코딩 되며 램에 저장된다. 인코딩은 다음과 같다.
100: 종료
2dn:d 레지스터를 n으로 설정( 0이상 9 이하)
3dn: d레지스터에 n 더함
4dn: d레지스터에 n 곱함
5ds: d 레지스터를 s 레지스터의 값으로 설정
6ds: s 레지스터의 값을 d 레지스터에 더함
7ds : d레지스터에 s 레지스터의 값을 곱함
8da : d 레지스터를 a 레지스터에 저장된 주소의 램에 들어있는 값으로 설정
9sa : a 레지스터에 저장된 주소의 램에 s 레지스터의 값을 대입
0ds : s 레지스터에 0 이 들어있지 않으면 d 레지스터에 있는 위치로 이동
모든 레지스터의 초기값은 000이다. 램에 저장되는 초기 값은 표준 입력으로부터 들어온다. 처음으로 실행될 명령은 주소가 0인 램에 들어있다. 모든 결과는 값이 1000이 넘어가면 1000으로 나눈 나머지로 줄어든다.
입력: 입력은 입력 케이스의 개수를 나타내는 양의 정수 한 개가 들어있는 줄로 시작되며 그 줄에는 그 숫자밖에 입력되지 않는다. 그 뒤에는 빈 줄이 하나 들어가고 서로 다른 입력 케이스 사이에는 빈 줄 두 개가 입력된다. 각 입력 케이스는 최대 1000개의 부호가 없는 세 자리 정수로 구성되며 그 숫자들은 0부터 시작하는 연속된 램 위치에 저장되는 내용을 나타낸다. 값이 지정되지 않는 램 위치는 000으로 초기화 된다.
출력:각 테스트 케이스마다 하나씩의 정수를 출력한다. 출력되는 정수는 종료 명령어에 이르기까지(종료 명령어 포함) 실행된 명령어의 개수다. 프로그램이 종료된다고 미리 가정해도 된다. 케이스가 여러 개 있는 경우에는 각 출력 사이에 빈 줄을 출력한다.
>>입력 예 >> 출력 예
1 16
299
492
495
399
492
495
399
283
279
689
078
100
000
000
000
풀이: 이 문제는 문제 자체는 아주 쉬우나 입력에 쓰이는 gets 함수의 정의를 제대로 파악하지 못해 풀이에 조금 오래 걸렸다. 그래서 풀이에는 입력 부분을 정리하려고 한다. 이 문제를 풀면서 알게 된 점은
1.*line은 line배열이 NULL 값을 가질 때 0이다.
2.gets는 개행문자를 만날 때 까지의 값을 입력 받는다. 따라서 scanf("%d",&a); gets(line); 이라고 하고, 1->enter 를 누르면 두 문장이 다 실행된다.
문제는 주어진 조건에 따라 적으면 풀린다.
소스코드:
#include <stdio.h>
void main(void)
{
int num_cases, num_executed;
int i, t, addr, pc, done, inst, arg1, arg2;
char line[100];
long reg[10], ram[1000];
scanf("%d", &num_cases);
gets(line);
gets(line);
for(t=0;t< num_cases; t++) {
for(addr = 0; gets(line) && *line;addr++) //line 입력
sscanf(line, "%d" , &ram[addr]);
for(; addr < 1000; addr++)
ram[addr]=0; // ram 초기화
for(i = 0 ; i < 10; i++)
reg[i]=0; //reg 초기화
num_executed = 0;
pc=0;
done = 0;
while(!done) {
inst = ram[pc] /100;
arg1 = (ram[pc] / 10) % 10;
arg2 = ram[pc] % 10;
pc++;
num_executed++;
switch(inst){
case 1:
done = 1;
break;
case 2:
reg[arg1] = arg2;
break;
case 3:
reg[arg1] = (reg[arg1] + arg2) % 1000;
break;
case 4:
reg[arg1] = (reg[arg1] * arg2) % 1000;
break;
case 5:
reg[arg1] = reg[arg2];
break;
case 6:
reg[arg1] = (reg[arg1] + reg[arg2]) % 1000;
break;
case 7:
reg[arg1] = (reg[arg1] * reg[arg2]) % 1000;
break;
case 8:
reg[arg1] = ram[reg[arg2]];
break;
case 9:
ram[reg[arg2]] = reg[arg1];
break;
case 0:
if(reg[arg2] != 0)
pc = reg[arg1];
break;
}
}
if(t>0)
putchar('\n');
printf("%d\n", num_executed);
}
}
'2009~2014 > C/C++' 카테고리의 다른 글
stack (0) | 2011.05.14 |
---|---|
list (0) | 2011.05.14 |
[C언어 기출문제&풀이] 그래픽 편집기(Graphical Editor) (0) | 2011.05.13 |
[C언어 기출문제&풀이] LCD 디스플레이 (0) | 2011.05.13 |
[C언어 기출문제&풀이] 여행(the trip) (0) | 2011.05.13 |