일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 배열
- 정보과학
- 독서 감상문
- 독후감
- IT
- C++
- DBMS
- Backdoor
- 리눅스 명령어
- API
- if문
- 참조은요양병원
- C
- 영재교육원
- 프로그래밍
- 수학영재원
- 풀이&소스코드저작권:왕유승
- 백도어
- For문
- 반복문
- 리눅스
- c언어
- 문제출저:www.dovelet.com
- 정보영재원
- 제어문
- Linux
- 정보올림피아드
- 자료구조
- 알고리즘
- 다중반복문
- Today
- Total
되는대로 살자
[C언어 기출문제&풀이] 체크확인 (Check the Check) 본문
체스판 설정을 읽어서 킹이 공격받고 있는지(체크상태인지)확인하는 일을 해야한다. 상대방의 다음 수에 의해 킹이 죽을 수 있는 위치에 있으면 킹이 체크 상태가 된다.
흰 말은 대문자로, 검은 말은 소문자로 표시된다. 흰 편은 항상 판의 아래쪽에, 검은 편은 판의 위쪽에 자리잡는다.
체스를 잘 모르는 사람들을 위해 각 말의 이동 방법을 설명하자면 다음과 같다.
폰(Pawn,p orP)한 번에 한 칸씩 앞으로만 갈 수 있다. 하지만 대각선에 있는 상대 말을 잡을 수 있으며 이 문제에서 이 부분에 주의해야 한다.
나이트(Knight, n or N):아래에 나와있는 것처럼 L자 모양으로 움직일 수 있다. 다른 말을 뛰어넘을 수 있는 유일한 말이다.
비숍(Bishop,b or B): 대각선 방향을 ㅗ어느 쪽으로든 이동 거리에 제한을 받지 않고 움직일 수 있다.
룩(Rook, r or R): 수직 또는 수평 방향을 ㅗ이동 거리에 제한을 받지 않고 움직일 수 있다.
퀸(Queen, q or Q):수직, 수평, 대각선 방향으로 어느 쪽으로든 이동 거리에 제한을 받지 않고 움직일 수 있다.
킹(King, k or K):수직, 수평, 대각선 방향으로 어느쪽으로든 한 칸을 움직일 수 있다.
그림 생략
다른 말을 건너뛸 수 있는 것은 나이트밖에 없다는 것을 꼭 기억해두자. 폰의 움직임은 어느 편인가에 따라 다르다. 검은 폰이면 아래쪽 대각선 방향으로, 흰색 폰이면 위쪽 대각선 방향으로 한 칸만 움직일 수 있다.
입력:입력에는 임의 개수의 체스판 배치가 들어있을 수 있으며 각 판은 각각 여덟 개 문자로 구성된 여덟 줄로 구성된다. ","은 빈 칸을 의미하며 위에서 정의했듯이 각 말을 의미하는 대문자 또는 소문자가 입력된다.
틀린 문자는 없으며 두 킹이 모드 체크를 당하는 배치는 입력되지 않는다. "," 문자만으로 구성된 비어있는 체스판이 나올 때 까지 입력을 읽어야 하며 비어있는 체스판은 처리하지 않는다. 각 체스판 배치 사이에는 빈 줄이 하나씩 들어간다. 비어있는 판을 제외한 모든 판에는 정확하게 하나씩의 흰 킹과 검은 킹이 들어있다.
풀이: 먼저 검은 색의 킹이 확인한 다음 흰색 킹이 체크되어있는지를 확인한다. 이때 검은 킹을 확인한 다음 판을 뒤집어서(turn_inside_down()) 흰색을 다시 검색한다. 매크로인 switch_case는 알파벳의 대소문자를 바꿔준다.(검은 말과 흰색 말을 바꾸기 위해서) 체크가 되어 있는지에 대한 검색은 킹에서부터 검사를 시작하며, 모든 말의 움직임에 대하여 체크한다. look_for_piece(char piece, int istart, int jstart, int di, int dj) 함수는 말 그대로 말을 찾아준다.
소스코드
#include <stdio.h>
#include <string.h>
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define switch_case(c) ((c) == '.' ? '.' : ((c) <='Z' ? \
((c) + 'a' - 'A') : ((c) + 'A' - 'a')))
char board[8][8];
void turn_upside_down()
{
int i,j;
char temp;
for(i=0;i<4;i++)
for(j=0;j<8;j++) {
temp = board[i][j];
board[i][j] = switch_case(board[7-i][7-i]);
board[7-i][7-i] = switch_case(temp);
}
}
int look_for_piece(char piece, int istart, int jstart, int di, int dj)
{
int i=istart + di, j=jstart+dj;
while(i >=0 && j<=7 && j>=0 && j<=7 && board[i][j] == '.'){
i+=di; j+=dj;
}
return (i>=0 && j<=7 && j>=0 && j<=7 && board[i][j] == piece);
}
int black_king_in_check()
{
int i,j,iking,jking;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
if(board[i][j]=='k'){
iking=i;
jking=j;
break;
}
if(iking <=6 && jking >= 1 && board[iking+1][jking-1]=='P'
|| iking <= 6 && jking <= 6 && board[iking+1][jking+1]== 'P')
return 1;
if(iking <=6 && jking<=5&&board[iking+1][jking+2] =='N'
|| iking <=6 && jking >= 2 && board[iking+1][jking-2] =='N'
|| iking >=1 && jking <=5 && board[iking-1][jking+2] == 'N'
|| iking >=1 && jking >=2 && board[iking-1][jking-2] == 'N'
|| iking <=5 && jking <=6 && board[iking+2][jking+1] == 'N'
|| iking <=5 && jking >=1 && board[iking+2][jking-1] == 'N'
|| iking >=2 && jking <=6 && board[iking-2][jking+1] == 'N'
|| iking >=2 && jking >=1 && board[iking-2][jking-1] == 'N')
return 1;
if(look_for_piece('B',iking,jking,1,1)
||look_for_piece('B',iking,jking,1,-1)
||look_for_piece('B',iking,jking,-1,1)
||look_for_piece('B',iking,jking,-1,-1))
return 1;
if(look_for_piece('R',iking,jking,1,0)
||look_for_piece('R',iking,jking,-1,0)
||look_for_piece('R',iking,jking,0,1)
||look_for_piece('R',iking,jking,0,-1))
return 1;
if(look_for_piece('Q',iking,jking,1,1)
||look_for_piece('Q',iking,jking,1,-1)
||look_for_piece('Q',iking,jking,-1,1)
||look_for_piece('Q',iking,jking,-1,-1)
||look_for_piece('Q',iking,jking,1,0)
||look_for_piece('Q',iking,jking,-1,0)
||look_for_piece('Q',iking,jking,0,1)
||look_for_piece('Q',iking,jking,0,-1))
return 1;
for(i=max(iking -1,0); i<=min(iking+1,7); i++)
for(j=max(jking-1,0);j<=min(jking+1,7); j++)
if(board[i][j]== 'K')
return 0;
return 0;
}
void main(void)
{
int empty_board;
int i,t;
t=0;
while(1)
{
empty_board=1;
for(i=0;i<8;i++)
if(strcmp(gets(board[i]),"........"))
empty_board =0;
if(empty_board)
break;
printf("Game #%d: ",++t);
if(black_king_in_check())
printf("black");
else
{
turn_upside_down();
if(black_king_in_check())
printf("white");
else
printf("no");
}
printf(" king is in check.\n");
gets(board[0]);
}
}
'2009~2014 > C/C++' 카테고리의 다른 글
[C언어 기출문제&풀이] 유쾌한 점퍼(jolly Jumpers) (0) | 2011.05.15 |
---|---|
[C언어 기출문제&풀이] 후보식 투표법(Australian Voting) (0) | 2011.05.15 |
queue (0) | 2011.05.14 |
stack (0) | 2011.05.14 |
list (0) | 2011.05.14 |