SHISENSHO문제를 푸는데 RTE오류가 발생하는데 이유를 모르겠습니다.

  • susul89
    susul89

    사천성 문제인데요...
    RTE (SIGSEGV: segmentation fault, probably incorrect memory access or stack overflow)\
    오류가 발상합니다. 비주얼스투디오로 컴파일 할때는
    오류없이 답이 잘 출력이 되는데요...
    어느부분이 문제인지 모르겠습니다.

    알고리즘이 길어서 조금 설명을 해 드리면
    문자가 있는 좌표값을 각각 받아서
    같은 문자가 있는 곳 까지 3번안에 가는 방법을 검색합니다
    '.'이아니거나 사천성 크기의 제일 끝으로 가게되면
    그 부딪힌 부분이 자신과 맞는 문자쌍인지 확인을 하고
    아니면 모든 경우의 수를 또 확인해 나갑니다.

    +한가지 질문을 더 드리자면
    너무 알고르짐이 길어지고, 단순하게 모든 경우의 수를
    확인하는 알고리즘이 되었는데 뭔가 찝찝하네요
    저의 접근방향이 잘못된 것인가요?

    #include <iostream>
    #include<string>
    #include <string.h>
    
    
    using namespace std;
    
    string Matrix[55];
    int Row, Col, z, TotalAnswer = 0;
    
    class Answer
    {
    public:
        char chr;
        int coll;
        int row;
    
    };
    
    bool AnswerCheck(Answer Start, Answer Target);
    
    int main()
    {
        int Count;
        cin >> Count;
        while (Count--)
        {
            Row = 0; Col = 0; z = 0; TotalAnswer = 0;
            //string Char[26];
            Answer RAnswer[2500];
            cin >> Col >> Row;
    
    
    
            for (int i = 0; i < Col; i++)
            {
                cin >> Matrix[i];
            }
            Col -= 1;
            Row -= 1;
    
    
            //공백이 아닌 문자를 가진걸 찾아 정의한 클래스안에 정보 저장
            for (int i = 1; i < Col ; i++)
            {
                for (int j = 1; j < Row ; j++)
                {
                    if (Matrix[i][j] != '.')
                    {
                        RAnswer[z].chr = Matrix[i][j];
                        RAnswer[z].coll = i;
                        RAnswer[z].row = j;
                        z++;
    
                    }
                }
            }
    
    
    
    
            //같은 문자쌍 확인
            for (int i = 0; i < z; i++)
            {
                for (int j = i + 1; j < z; j++)
                {
                    if (RAnswer[i].chr == RAnswer[j].chr)
                    {
                        //함수 호출
                        if (AnswerCheck(RAnswer[i], RAnswer[j]))
                        {
                            TotalAnswer += 1;
                            //cout << i << "=>" << j << endl;
                        }
                    }
                }
            }
            cout << TotalAnswer<<endl;
        }
    
    }
    
    bool AnswerCheck(Answer Start, Answer Target)
    {
        int SourceColl = Start.coll;
        int SourceRow = Start.row;
        int TempColl = Start.coll;
        int TempRow = Start.row;
    
    
        //왼쪽 체크
        if ((Start.row - 1 >= 0 && Matrix[Start.coll][Start.row - 1] == '.') || Start.row - 1 == Target.row && Start.coll == Target.coll)
        {
    
            if (Start.row - 1 == Target.row && Start.coll == Target.coll){
                return true;
            }
            //왼쪽이 0이되거나 벽이 막힐떄 까지 계속감 
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.'; i--)
            {
                Start.row--;
            }
            //부딪힌게 같은 문자인가 같은 문자면 트루값을 리턴
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
            }
    
    
            //한번꺾었다!!!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    
            TempColl = Start.coll;
            TempRow = Start.row;
    
            //아니면 위나 아래로다시 진행 , 먼저 위
            for (int i = Start.coll; i > 0 && Matrix[Start.coll - 1][Start.row] == '.' && i<Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll - 1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
    
    
            ////두번쨰 꺾어사 오른쪽 왼쪽  진행!!!
            //위로 올라온후 무언가에 부딪히고, 좌나 우로 진행, 좌먼저
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
    
    
    
    
            //그다음 우진행
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
    
    
            //처음꺽고 위쪽으로 가는 경우 다 조사했고 아래쪽으로 가는 경우 다 조사하자!!!
    
            Start.coll = TempColl;
            Start.row = TempRow;
    
            //다음 아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll + 1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
    
            ///아래 내려와서 좌 우 진행  먼저 왼쪽!!!
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
    
    
            //그다음 우진행
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
        }
        Start.row = SourceRow;
        Start.coll = SourceColl;
        //오른쪽 체크
        if ((Start.row + 1 <= Row && Matrix[Start.coll][Start.row + 1] == '.') || (Start.row + 1 == Target.row && Start.coll == Target.coll))
        {
            if (Start.row + 1 == Target.row && Start.coll == Target.coll)
                return true;
    
            //오른쪽으로 쭉가는 거 확인
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.'; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
    
            //값 저장하고
            TempColl = Start.coll;
            TempRow = Start.row;
            //위쪽 간후
            for (int i = Start.coll; i > 0 && Matrix[TempColl - 1][Start.row] == '.' && i>Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //좌
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
            //우
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
            //저장한 값 불러온 후
            Start.coll = TempColl;
            Start.row = TempRow;
            //아래로
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll+1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //좌
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
            //우
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
    
        }
        //처음값 불러오기
        Start.row = SourceRow;
        Start.coll = SourceColl;
        //위쪽 체크
        if ((Start.coll - 1 >= 0 && Matrix[Start.coll - 1][Start.row] == '.') || (Start.row == Target.row && Start.coll - 1 == Target.coll))
        {
            if (Start.row == Target.row && Start.coll - 1 == Target.coll)
                return true;
    
            //위쪽 끝까지 가고
            for (int i = Start.coll; i >0 && Matrix[Start.coll-1][Start.row] == '.' ; i--)
            {
                Start.coll--;
            }
            if (Start.coll-1 == Target.coll&&Start.row== Target.row)
            {
                return true;
    
            }
            //중간값 저장
            TempColl = Start.coll;
            TempRow = Start.row;
            //오른쪽 
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
            //위
            for (int i = Start.coll; i > 0 && Matrix[TempColl - 1][Start.row] == '.' && i>Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll+1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //중간값 불름
            Start.coll = TempColl;
            Start.row = TempRow;
            //왼쪽
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
            //위
            for (int i = Start.coll; i > 0 && Matrix[TempColl - 1][Start.row] == '.' && i>Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
    
        }
        Start.row = SourceRow;
        Start.coll = SourceColl;
        //처음값 불러오기
        //아래쪽 체크
        if ((Start.coll +1 <= Col && Matrix[Start.coll + 1][Start.row] == '.') || (Start.row == Target.row && Start.coll + 1 == Target.coll))
        {
            if (Start.row == Target.row && Start.coll + 1 == Target.coll)
                return true;
    
            //아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' ; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll+1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //중간값 저장
            TempColl = Start.coll;
            TempRow = Start.row;
            //왼
            for (int i = Start.row; i > 0 && Matrix[Start.coll][Start.row - 1] == '.' && i>Target.row; i--)
            {
                Start.row--;
            }
            if (Start.coll == Target.coll&&Start.row - 1 == Target.row)
            {
                return true;
    
            }
            //위
            for (int i = Start.coll; i > 0 && Matrix[TempColl - 1][Start.row] == '.' && i>Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll+1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //중간값 불러오기
            Start.coll = TempColl;
            Start.row = TempRow;
            //오른쪽
            for (int i = Start.row; i <Row && Matrix[Start.coll][Start.row + 1] == '.' && i<Target.row; i++)
            {
                Start.row++;
            }
            if (Start.coll == Target.coll&&Start.row + 1 == Target.row)
            {
                return true;
    
            }
    
            for (int i = Start.coll; i > 0 && Matrix[TempColl - 1][Start.row] == '.' && i>Target.coll; i--)
            {
                Start.coll--;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll-1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
            //아래
            for (int i = Start.coll; i < Col && Matrix[Start.coll + 1][Start.row] == '.' && i<Target.coll; i++)
            {
                Start.coll++;
            }
            //부딪힌게 같은 A인가 확인, A이면
            if (Start.coll+1 == Target.coll&&Start.row == Target.row)
            {
                return true;
    
            }
        }
        return false;
    }
    

    문단을 구분하기 위해 앞과 뒤에 빈 줄 하나씩을 반드시 추가하셔야 합니다.


    마지막으로 자주_하는_실수_모음 페이지를 읽으시면서 혹시 해당되는 사항이 있진 않은지 생각해 보세요.

    위 내용이 지켜지지 않은 질문은 답변이 오래 걸릴 수 있습니다.

    아래 '편집하기' 버튼을 눌러 글을 쓰실 수 있습니다.


    8년 전
1개의 댓글이 있습니다.
  • JongMan
    JongMan

    SIGSEGV 오류는 대개 잘못된 메모리 접근으로 발생합니다. 많은 경우 배열 범위 밖의 값에 접근할 때 발생하죠. 코드가 이렇게 길고 복잡하면 이런 문제를 찾기 어려워집니다.

    더 간단하게 짜는 방법이 있으실 것 같네요. ^^; 2번 꺾는 모든 방법을 하드코딩하지 않고 짜는 방법을 생각해 보세요.


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