MORSE문제에서 SIGFEV가 계속 뜹니다.

  • yhb0730
    yhb0730

    MORSE문제를 제출했는데 SIGFEV 시그널이 계속 뜹니다. 찾아보니 SIGFEV는 연산 관련해서 오류가 있을경우 반환된다고 적혀있는데 오류가 날것같은 부분들은 고쳐보고 나머지 연산들도 확인해 봤는데 어디서 자꾸 오류가 나는지 모르겠습니다. 어디가 문제인지 알 수 있을까요?

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<vector>
    #define MAX 100
    
    using namespace std;
    
    inline void input();
    
    void makeAll(int cur, string res, int shortRes, int longRes);
    int Combination(int n, int r);
    int Solve(int fixed, int pick, int limit);
    void algorithm();
    void reconstruct();
    
    int n, m, k, size, ansNum;
    int cache[MAX+1][MAX+1]; //첫번째 : 어디서, 두번째 : 몇개를 고르느냐 저장
    vector<int> container;
    
    int main(void)
    {
        int testcase;
        cin.sync_with_stdio(false);
        cout.sync_with_stdio(false);
        cin >> testcase;
        memset(cache, 0, sizeof(cache));
        while (testcase--)
        {
            input();
            //makeAll(0, "", n, m);
            algorithm();
            reconstruct();
        }
        return 0;
    }
    
    inline void input()
    {
        cin >> n >> m >> k;
        size = n + m;
        ansNum = 0;
        container.clear();
    }
    
    void makeAll(int cur, string res, int shortRes, int longRes) //제대로 된 답 확인하기 위해 만든 간단한 함수 -> 답 낼때는 주석처리
    {
        if (cur == size){
            if (++ansNum == k){
                cout << "답 : " << res << '\n';
                cout << "-----------------------" << '\n';
            }
            return;
        }
    
    
        if (ansNum == k) return;
    
        if (shortRes){
            makeAll(cur + 1, res + '-', shortRes-1, longRes);
        }
    
        if (ansNum == k) return;
    
        if (longRes){
            makeAll(cur + 1, res + 'o', shortRes, longRes-1);
        }
    }
    
    void algorithm()
    {
        int total = 0, start = 0, tempM = m;
        while (1){
            start = Solve(tempM, tempM, k-total); //start를 정하고 나서는 다시 처음으로 돌아가서 남은거 시도하니까 항상 fixed는 tempM, pick도 tempM
            total += cache[start-1][tempM]; //start가 고정됬을때 요구사항을 만족하므로 start-1의 경우(전체) + start의 경우(부분)이 답이기 때문에 저 캐시 저장
            container.push_back(start); //가장 위의 숫자 저장
            if (--tempM == 0 || total == k){ //하나 골랐으니 pick과 fixed를 떨굼 -> 아래 while문 때문에 단축평가가 일어나면 안되니 tempM이 먼저 나옴
                while (tempM-- > 0)
                {
                    container.push_back(--start); //tempM이 0이 아닌데 끝난거는 딱 맞아 떨어지는 경우(=마지막에서 전부 붙어있는 경우)이니 연달아 넣음
                }
                break;
            }
        }
    }
    
    int Solve(int fixed, int pick, int limit) //fixed => 고정되는 숫자, pick => 골라야하는 숫자, limit => 넘어가면 종료
    {
        int &ret = cache[fixed][pick]; //fixed 부분에서 pick 고를 때의 경우의 수 메모제이션
        if (ret == 0){ //여기다가 if(ret!=0) return ret; 했는데 여기 ret는 경우의 수니까 return 시키면 망함. 콤비네이션 계산을 스킵해야함
            ret = Combination(fixed - 1, pick - 1) + cache[fixed - 1][pick]; //fixed부분에 o가 들어갔다고 생각하고 만드는 콤비네이션, 하나 정하고 그 밑에서 확인하니 fixed-1, pick-1
        }
        if (ret >= limit)
        {
            return fixed;
        }
        return Solve(fixed + 1, pick, limit);
    }
    
    int Combination(int n, int r) //nCr 구하는 함수
    {
        if (n == r || n < 1 || r == 0) return 1;
        if (r == 1) return n;
    
        int res = 0, numerator = 1, denominator = 1;
        for (int i = n; i > r; --i)
        {
            numerator *= i;
        }
    
        for (int i = n - r; i > 1; --i)
        {
            denominator *= i;
        }
        if (denominator != 0){
            res = numerator / denominator;
        }
        else
        {
            cout << "오답내기"; //오답을 일부로 냈는데 안 남 -> SIGFEP 원인 아님
        }
        return res;
    }
    
    void reconstruct() //답 만들어내는 함수 (벡터에 몇번째 모스부호가 o가 되어야하는지 저장중)
    {
        int answer[201] = {0,};
        for (auto t : container)
        {
            answer[t] = 1; //원래 'o' 였음. 혹시 캐스팅 안한게 문젠가 싶어서 바꿔봤는데 SIGFEV 원인 아님
        }
        for (int i = size; i > 0; --i)
        {
            if (answer[i] == 1){
                cout << 'o';
            }
            else
            {
                cout << '-';
            }
        }
        cout << '\n';
    }
    

    6년 전
0개의 댓글이 있습니다.
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.