디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

c언어에 능통한 분들에게 질문좀 드리고 싶습니다.

프로게래밍(121.143) 2009.08.11 17:07:31
조회 193 추천 0 댓글 10

어제도 질문 올렸었는데요.


어제 밤에 코드를 다 완성했는데..

값이 제대로 안 나오네요.        

문제는 koi4u 실전문제 2번. 다리만들기 입니다

2번 - 다리 만들기

 

 

bar1.gif

<ul>

여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은, 섬들을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다는 생각을 하게 되었다. 그래서 그는, 생색내는 식으로 한 섬과 다른 섬을 잇는 다리 하나만을 만들기로 하였고, 그 또한 다리를 가장 짧게 하여 돈을 아끼려 하였다.

이 나라는 NxN크기의 이차원 평면상에 존재한다. 이 나라는 여러 섬으로 이루어져 있으며, 섬이란 동서남북으로 육지가 붙어있는 덩어리를 말한다. 다음은 세 개의 섬으로 이루어진 나라의 지도이다.

p2-1.gif

위의 그림에서 색이 있는 부분이 육지이고, 색이 없는 부분이 바다이다. 이 바다에 가장 짧은 다리를 놓아 두 대륙을 연결하고자 한다. 가장 짧은 다리란, 다리가 격자에서 차지하는 칸의 수가 가장 작은 다리를 말한다. 다음 그림에서 두 대륙을 연결하는 다리를 볼 수 있다.

p2-2.gif

물론 위의 방법 외에도 다리를 놓는 방법이 여러 가지 있으나, 위의 경우가 놓는 다리의 길이가 3으로 가장 짧다(물론 길이가 3인 다른 다리를 놓을 수 있는 방법도 몇 가지 있다)

지도가 주어질 때, 가장 짧은 다리 하나를 놓아 두 대륙을 연결하는 방법을 찾으시오. 답이 여러 개인 경우, 그 중 하나만 출력한다. 실행파일은 p2.exe, 소스 파일은 언어에 따라 p2.c, p2.cpp, p2.pas, p2.bas 로 작성한다.

찾은 다리의 길이가 최소가 아니라도, 부분점수가 있다.

</ul>

bar2.gif

<ul>

입력파일은 p2.in이다. 맨 첫 줄에는 지도의 크기 N(100이하의 자연수)가 주어진다. 그 다음 N줄에는 N개의 숫자가 빈칸을 사이에 두고 주어지며, 0은 바다, 1은 육지를 나타낸다.

</ul>

bar3.gif

<ul>

출력파일은 p2.out이다. 첫 줄에는 찾은 다리의 길이, 그 다음에는 그 길이 만큼의 줄에 다리를 놓은 좌표를 순서없이 출력한다. 입출력 예를 참고하도록 한다.

</ul>

bar4.gif

<ul>

p2.in 

10
1 1 1 0 0 0 0 1 1 1
1 1 1 1 0 0 0 0 1 1
1 0 1 1 0 0 0 0 1 1
0 0 1 1 1 0 0 0 0 1
0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0

p2.out 

3
6 4
7 4
7 5

</ul>

bar5.gif

<ul type="disc"><li>제한시간은 10초이다.</li><li>섬의 개수에는 제한이 없다.</li></ul>


저작권에 걸리려나..

저는 우선, 
육지와 바다를 구분하고,
육지를 다시 각각의 섬으로 구분하여
2,3,4... 로 바꾸려고 계획했습니다..

예를들면
2 2 2 0 0 0 0 3 3 3
2 2 2 2 0 0 0 0 3 3
2 0 2 2 0 0 0 0 3 3
0 0 2 2 2 0 0 0 0 3
0 0 0 2 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 0
0 0 0 0 4 4 0 0 0 0
0 0 0 0 4 4 4 0 0 0
0 0 0 0 0 0 0 0 0 0
이렇게요.

그리고 해안선을 찾아 해안선에는 각각의 수에 10씩을 더 했죠.
\'2\'섬의 해안선에는 12
\'3\'섬의 해안선에는 13..

그리고 각각의 해안선끼리 빼서

다리의 최소값을 찾는 코드를 썼습니다..


하지만...

각각의 섬으로 구별하는 부분부터 문제가 생기네요..
위의 내용대로 하면
2 2 2 0 0 0 0 3 3 3
2 2 2 2 0 0 0 0 3 3
2 0 2 2 0 0 0 0 3 3
0 0 2 2 2 0 0 0 0 3
0 0 0 2 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 0
0 0 0 0 4 4 0 0 0 0
0 0 0 0 4 4 4 0 0 0
0 0 0 0 0 0 0 0 0 0
가 나와야 하는데

3 3 3 0 0 0 0 3 3 3
3 3 3 3 0 0 0 0 3 3
3 0 3 3 0 0 0 0 3 3
0 0 3 3 3 0 0 0 0 3
0 0 0 3 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0 0 0
0 0 0 0 3 3 0 0 0 0
0 0 0 0 3 3 3 0 0 0
0 0 0 0 0 0 0 0 0 0

이렇게 나오네요..

어디가 문제일까요?


코드는 이렇습니다.

#include <stdio.h>
void main()
{

        int n,x[100][100],c=2,cou=100,cou2;
        //x는 지도, c는 섬의 갯수이자 번호(2부터 시작하는 이유는 0,1은 바다인지 땅인지 구별하는데 쓰이므로)
        //cou는 다리의 최소값, cou는 비교값
        int g=0,h=0,i,j,cc;
        //g,h는 2차원 배열을 비교하기 위해 만든 변수 
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
                for(j=0;j<n;j++)
                {
                        scanf("%d",&x[i][j]);
                }
        }
        //지도는 NxN으로 이루어지므로
        //입력 끝
        for(i=0;i<n;i++)                
        {
                for(j=0;j<n;j++)        
                {
                        if(x[i][j]==1) //x[i(행)][j(열)]이 1일 경우(육지일경우)
                        {
                                for(h=2;h<=c;h++)  //반복문으로 c(섬의 번호)를 계속 초기화 하여 비교할 수 있음
                                {
                                        c=h;
                                        if(x[i+1][j]==c) 
                                        {
                                                x[i][j]=c; //x[i][j]보다 1행(한칸 위)가 c라면(c의 초기값은 2이다.) x[i][j]에도 c를 넣어라
                                        }
                                        if(x[i-1][j]==c)
                                        {
                                                x[i][j]=c; //이건 한칸 아래
                                        }
                                        if(x[i][j+1]==c)
                                        {
                                                x[i][j]=c; //이건 한칸 앞
                                        }
                                        if(x[i][j-1]==c)
                                        {
                                                x[i][j]=c; //이건 한칸 뒤
                                        }
                                }
                        }
                        if(x[i][j]==1) //그래도 값이 변하지 않았다.(이 땅 주변에 기존에 있는 섬은 없다.)
                        {
                                c++;        //c를 1증가(주변에 섬이 없으므로 새로운 섬의 번호를 부여)
                                x[i][j]=c; //그리고 증가한 c를 x[i][j]에 대입
                        }
                }
        }
        for(i=0;i<n;i++)
        {
                for(j=0;j<n;j++)
                {
                        for(h=2;h<c;h++) //섬의 번호에 포함되는지 비교하기 위함
                        {
                                if(x[i][j]==h)        //만약 h가 섬이라면
                                {
                                        if(x[i++][j]==0)
                                        {
                                                x[i][j]+=10; //i행 위에 바다가 있다면 값에 10을 증가시킨다.
                                                                         //이렇게 10이 증가된 땅은 해안섬이다.
                                        }
                                        if(x[i--][j]==0)
                                        {
                                                x[i][j]+=10; //한칸 아래
                                        }
                                        if(x[i][j++]==0)
                                        {
                                                x[i][j]+=10; //한칸 앞
                                        }
                                        if(x[i][j--]==0)
                                        {
                                                x[i][j]+=10; // 한칸 뒤
                                        }
                                }
                        }
                }
        }
        for(;;) //무한루프(라곤 하지만 h가 n을 넘어가면 끝남)
        {
                if(x[h][g]>10) //만약 x[h][g]가 10 이상이라면(해안선이라면)
                {
                        for(i=0;i<n;i++)
                        {
                                for(j=0;j<n;j++) //2차원 배열 비교
                                {
                                        if(x[i][j]>10) //x[i][j]가 10이상이라면 (비교 대상도 해안선일 경우에만 아래 내용을 수행)
                                        {
                                                if(x[h][g]!=x[i][j]) //비교대상과 비교하는 값이 다를 경우에만 아래 내용을 수행
                                                {
                                                        if(h>i)
                                                        {
                                                                cou2=(h-i);        //h와 i의 차를 구한다.
                                                        }
                                                        else
                                                        {
                                                                cou2=(i-h);
                                                        }
                                                        if(g>j)
                                                        {
                                                                cou2+=(g-j); //g와 j의 차를 더한다
                                                        }
                                                        else
                                                        {
                                                                cou2+=(j-g);
                                                        }
                                                }
                                                if(cou2<cou)
                                                {
                                                        cou=cou2; //그게 cou(초기값 100)보다 작으면 cou에 cou2를 대입
                                                }
                                        }
                                }
                        }
                }
                g++; //g를 증가
                if(g>=n) //g가 n보다 크거나 같다면 g를 0으로 바꾸고 h를 증가
                {
                        g=0;
                        h++;
                        if(h>=n)
                        {
                                break;        //h가 n이 되는순간 for문 폭파
                        }
                }
        }
        //그리고 출력
        for(i=0;i<n;i++)
        {
                for(j=0;j<n;j++)
                {
                        printf("%d",x[i][j]);
                }
                printf("\\n");
        }
}









제발 문제점좀 찾아주세요..

엄청 힘들게 짰는데 이렇게 나오니.. 허탈하네요


대략 3번정도 처음부터 끝까지 훑어봤는데.. 제대로 안 나오네요..

제 컴퓨터가 문제일까요?

주변에 아는사람도 없고.. 지식인같은곳에서도 만족한 답변을 찾을 수 없었습니다.

오류,경고메시지는 안뜨네요.

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 비난 여론에도 뻔뻔하게 잘 살 것 같은 스타는? 운영자 24/06/03 - -
154750 라이티치횽은 봄니다!! [11] 개쉛기갤로그로 이동합니다. 09.10.29 102 0
154749 좋은 프로그래밍 기술 조언드립니다. [12] 이에갤로그로 이동합니다. 09.10.29 163 0
154748 Gromit 횽아는 봅니다. [14] 물속의다이아갤로그로 이동합니다. 09.10.29 119 0
154747 괜히 올려서 미안 [16] brian(216.45) 09.10.29 164 0
154746 학생들이 씨발 몰라서 물어볼수도 있지 뭘 그렇게 까대기 바쁘냐 이새끼들아 [6] 아주아슬갤로그로 이동합니다. 09.10.29 178 0
154745 학생들이 씨발 몰라서 물어볼수도 있지 뭘 그렇게 까대기 바쁘냐 이새끼들아 [8] 씬입사원갤로그로 이동합니다. 09.10.29 174 0
154744 학생들이 씨발 몰라서 물어볼수도 있지 뭘 그렇게 까대기 바쁘냐 이새끼들아 [10] 개쉛기갤로그로 이동합니다. 09.10.29 272 0
154741 형님들 c++이렇게 짜는게 맞나요? [13] dd(119.70) 09.10.29 177 0
154739 포트란으로 할만한 프로젝트가 뭐 있을까요? [6] Euler갤로그로 이동합니다. 09.10.29 111 0
154738 실무경험 있는 형들에게 질문좀^^ [8] ㅁㄴㅁㄴ(222.111) 09.10.29 127 0
154737 C# 유저분들. [8] ㅇㄴㅣㅏ갤로그로 이동합니다. 09.10.29 130 0
154736 윈도우7 프로 홈파는데 왜 울티버전은 안팔죠? [4] 헐ㅋㅋ(118.218) 09.10.29 118 0
154734 마법을 걸겠어요. [5] algo갤로그로 이동합니다. 09.10.29 125 0
154733 인상이 매우 중요한거 같다. [14] DMW(220.68) 09.10.29 232 0
154732 고민된다 [30] 고추장불고기갤로그로 이동합니다. 09.10.29 250 0
154730 형들 나 소스코드 색입히는거때문에 질문이있습니당. [4] 형들(211.114) 09.10.29 101 0
154729 OOP 늅늅이가 질문을 합니다. [2] 오버액션.갤로그로 이동합니다. 09.10.29 99 0
154728 난형들이 무슨얘기하는지 도대체 알수가없다. [12] 개쉛기갤로그로 이동합니다. 09.10.29 171 0
154727 데이터가 순차적으로 정렬돼있다는 가정 하에 가장 효율적인 알고리즘 [10] 어쩌라는갤로그로 이동합니다. 09.10.29 160 0
154725 피곤함 속의 한잔... [5] 물속의다이아갤로그로 이동합니다. 09.10.29 117 0
154724 꼐임을 만들고싶은 프로그래밍 생초보는 뭘 봐야 하나요? [6] S. 메시에갤로그로 이동합니다. 09.10.29 132 0
154723 토발츠 아저씨는 쿨하니깐요 [13] 고추장불고기갤로그로 이동합니다. 09.10.29 164 0
154722 윈도우7 설치 가능여부좀 판단부탁 [7] ㅋㅋ(61.97) 09.10.29 121 0
154719 나도 원래 이쪽 전공이었는데... [14] ㄷㅂ(128.101) 09.10.29 222 0
154718 소켓을 여러개 열어서 보내면 빨라집니까? [11] Vita500갤로그로 이동합니다. 09.10.29 155 0
154717 자바스크립트 특정달의 마지막날 알수있는 메소드 있나? [9] 신발라마갤로그로 이동합니다. 09.10.29 119 0
154716 횽들! [10] IHF갤로그로 이동합니다. 09.10.29 132 0
154715 헌재 "권한침해 있지만 신문법 유효"(5보) [11] 초밥술사(210.125) 09.10.29 143 0
154714 이런 코드 본적 있는사람? [5] 햏햏했갤로그로 이동합니다. 09.10.29 135 0
154713 클라이언트에서 패킷 보낼때... [10] 물속의다이아갤로그로 이동합니다. 09.10.29 132 0
154712 erd -> oracle [4] brian(156.56) 09.10.29 90 0
154711 디씨나왔다 [2] 개쉛기갤로그로 이동합니다. 09.10.29 85 0
154710 음.. 게임을 잘하는 체질도 있냐 ? [13] yundream(211.189) 09.10.29 178 0
154709 집중안되는 시간을 이용한 뻘글 -- 누구나 아는 finally [13] 아주아슬갤로그로 이동합니다. 09.10.29 128 0
154708 신종플루 걸리면 [8] 피로토스갤로그로 이동합니다. 09.10.29 132 0
154707 공연일정!! [5] 유리한갤로그로 이동합니다. 09.10.29 106 0
154705 자바스크립트 한글api 없나? [9] 신발라마갤로그로 이동합니다. 09.10.29 121 0
154704 아... 진짜 문서는 30분 이상 집중을 못하겠어. [9] 아주아슬갤로그로 이동합니다. 09.10.29 103 0
154703 점심 먹고 졸릴 시간.. 재미난 동영상 한편 감상 [1] 커널vDK갤로그로 이동합니다. 09.10.29 72 0
154702 Gromit 횽아는 봅니다. [14] 물속의다이아갤로그로 이동합니다. 09.10.29 117 0
154701 서양은 오덕도 수준급이라는데 사실인가여? [8] 씬입사원갤로그로 이동합니다. 09.10.29 200 0
154700 항방작계 후반기 [7] 유리한갤로그로 이동합니다. 09.10.29 124 0
154699 점심 패치... [17] 물속의다이아갤로그로 이동합니다. 09.10.29 164 0
154698 sql 인데 기초수준 강의인데 나좀 알려줘요 [5] brian(156.56) 09.10.29 92 0
154697 퀴즈!! 자바스크립트 상위 엘레먼트 접근할려면 어떻게 하면 될까? [9] 신발라마갤로그로 이동합니다. 09.10.29 83 0
154695 저는 아니예요 유리한갤로그로 이동합니다. 09.10.29 78 0
154694 접대도 당당하게 [13] 유리한갤로그로 이동합니다. 09.10.29 215 0
154693 결과 창 바로 꺼지는 문제.. [5] (125.186) 09.10.29 102 0
154692 존나 정독해야할 글. 여성심리를 존나파악한새키인듯. [10] 빕뱟뱟갤로그로 이동합니다. 09.10.29 212 0
154691 SCJP PLUS생기면서 기존 SCJP없어졌지? [3] 신발라마갤로그로 이동합니다. 09.10.29 108 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2