본문 바로가기

알고리즘 문제풀이/추천 문제

[ 백준 16506 ] CPU (C++)

반응형

https://www.acmicpc.net/problem/16506

 

16506번: CPU

디지털하드웨어설계 과목의 최종 프로젝트는 16-bit CPU를 설계하고 Verilog 언어로 구현하는 것이다. 본인이 구현한 CPU가 제대로 동작하는지 테스트하기 위해서는 기계어 코드를 입력으로 주어야

www.acmicpc.net

 

 

단순 구현 문제라 그냥 풀면 된다. 풀이 방법은 수없이 많을 것으로 생각된다.

 

나는 이 문제를 두 가지 함수를 이용해서 풀었다.

 

 

첫째로, 십진수를 이진수로 변환하는 함수가 필요하다. 이 과정에서 원하는 비트수만큼 0으로 채워주야 한다. 함수 입력값은 십진수 num과 비트수 크기에 해당하는 range다. 십진수를 이진수로 변환하는 알고리즘은 계속 2로 나눈 다음에 나머지를 더해주면 된다. 

 

// 십진수를 이진수로 변환, 비트수는 range
string get_binary(int num, int range){
    string binary = "";
    
    while((num / 2) != 0){
        if(num % 2 == 0) binary = '0' + binary;
        else binary = '1' +binary;
        
        num /= 2;
    }
    
    if(num % 2 == 0) binary = '0' + binary;
    else binary = '1' + binary;
    
    // 비트수 range 크기만큼 맞춰주기
    while(binary.length() != range){
        binary = '0' + binary;
    }
    
    return binary;
}

 

둘째로, opcode를 string 배열로 저장한 뒤에 인덱스와 c 여부를 추출하는 함수가 필요하다. c 여부는 opcode 뒤에 'C'가 붙는지를 말한다. c인지 아닌지에 따라 결과가 케이스가 나뉜다. 

 

// 문자열 검색 후 인덱스, c인지 반환
void get_index(string op, int& index, int& is_c){
    for(int i = 0; i < 12; i++){
        if(opcode[i] == op){
            index = i;
            is_c = 0;
            return;
        }
        else if(opcode[i] + 'C' == op){
            index = i;
            is_c = 1;
            return;
        }
    }
}

 

이제 아래 알고리즘을 그대로 따라가면 끝!

1. 인덱스, c 여부 구하기
2. range = 4, opcode 출력, c여부에 따라 0,1 출력
3. rD 출력. range = 3
4. rA 출력. range = 3
5. c 아니면 rB range = 3, c 이면 #C range = 4

 

#include <iostream>
#include <string>
#include <vector>
using namespace std;

string opcode[12] = {"ADD", "SUB", "MOV", "AND", "OR", "NOT", "MULT", "LSFTL", "LSFTR", "ASFTR", "RL", "RR"};

// 문자열 검색 후 인덱스, c인지 반환
void get_index(string op, int& index, int& is_c){
    for(int i = 0; i < 12; i++){
        if(opcode[i] == op){
            index = i;
            is_c = 0;
            return;
        }
        else if(opcode[i] + 'C' == op){
            index = i;
            is_c = 1;
            return;
        }
    }
}

// 십진수를 이진수로 변환, 비트수는 range
string get_binary(int num, int range){
    string binary = "";
    
    while((num / 2) != 0){
        if(num % 2 == 0) binary = '0' + binary;
        else binary = '1' +binary;
        
        num /= 2;
    }
    
    if(num % 2 == 0) binary = '0' + binary;
    else binary = '1' + binary;
    
    // 비트수 range 크기만큼 맞춰주기
    while(binary.length() != range){
        binary = '0' + binary;
    }
    
    return binary;
}


int main(){
    string op;
    int a, b, c, index, is_c, n;
    vector<string> ans;
    
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> op >> a >> b >> c;
        string tmp = "";
        
        // 1. 인덱스, c 여부 구하기
        get_index(op, index, is_c);
        
        // 2. range = 4, opcode 출력, c여부에 따라 0,1 출력
        tmp += get_binary(index, 4);
        if(is_c) tmp += '1';
        else tmp += '0';
        tmp += '0';
        
        // 3. rD 출력. range = 3
        tmp += get_binary(a, 3);
        
        // 4. rA 출력. range = 3
        tmp += get_binary(b, 3);
        
        // 5. c 아니면 rB range=3, c 이면 #C range = 4
        if(is_c) tmp += get_binary(c, 4);
        else tmp += get_binary(c, 3) + '0';
        
        ans.push_back(tmp);
    }
    
    for(int i = 0; i < n; i++)
        cout << ans[i] << endl;
    
    return 0;
}
반응형