일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 수학영재원
- 리눅스 명령어
- 프로그래밍
- c언어
- 자료구조
- 정보올림피아드
- Linux
- 영재교육원
- 다중반복문
- 정보영재원
- IT
- Backdoor
- 독서 감상문
- 제어문
- 리눅스
- C++
- if문
- 문제출저:www.dovelet.com
- 정보과학
- API
- 반복문
- C
- 풀이&소스코드저작권:왕유승
- For문
- 독후감
- 참조은요양병원
- 배열
- 백도어
- 알고리즘
- DBMS
- Today
- Total
되는대로 살자
[C언어 기출문제&풀이] 포커 패(Poker hands) 본문
포커용 카드느 52개의 카드로 이루어진다. 각 카드는 클럽, 다이아몬드, 하트, 스페이드(입력 데이터에서는 각각 C,D,H,S로 표기) 중 한 가지 무늬를 가진다. 또한 각 카드는 2에서 10까지, 그리고 잭, 퀸, 킹, 또는 에시스(2,3,4,5,6,7,8,9,T,J,Q,K,A로 표기)의 값을 갖는다. 점수를 매길 때 위에 열거한 순서대로 등급이 매겨지며 2가 가장 낮고 에이스가 가장 높다. 무늬는 값에 영향을 기치지 않는다.
포커 패는 다섯 장의 카드로 구성되며 다음과 같은 순서대로 등급이 매겨진다.
하이카드: 아래에 있는 것 가운데 어떤 범주에도 속하지 않는 패는 그 중 가장 높은 카드의 값에 따라 등급이 매겨진다. 가장 높은 카드의 값이 같으면 그 다음 카드, 그 다음 카드도 같으면 그 다음카드, 이런 식으로 등급이 매겨진다.
원 페어: 다섯 장의 카드 가운데 두 장이 같은 경우. 같은 원 페어끼리 맞붙는 경우에는 더 높은 값을 가지는 원 페어 패에 더 높은 등급이 매겨진다. 값까지 같은 경우에는 나머지 카드의 값에 의해 더 높은 패가 결정 된다.
투페어: 두 쌍의 카드가 같은 값을 가지는 경우. 투 페어끼리 맞붙는 경우에는 그 중 더 높은 페어의 값에 의해 더 높은 등급이 매겨진다. 두 쌍의 값이 모두 같으면 남은 카드에 의해 더 높은 패가 결정된다.
쓰리카드: 다섯 장 가운데 세 장이 같은 값을 가지는 경우. 쓰리 카드끼리 맞붙는 경우에는 세 장의 같은 값을 가지는 카드의 ㄱ밧에 의해 더 높은 패가 결정된다.
스트레이트: 다섯 장의카드가 연속적인 값을 가지는 경우. 스트레이트끼리 맞붙을 경우에는 가장 높은 카드에 의해 더 높은 패가 결정된다.
플러시: 다섯 장의 카드의 무늬가 모두 같은 경우. 플러시끼리 맞붙을 경우에는 하이 카드의 규칙에 따라서 더 높은 패가 결정된다.
풀 하우스: 세 장의 카드가 같은 값을 가지고 나머지 두 장의 카드가 같은 값을 가지는 경우. 같은 값을 가지는 세 장의 카드의 우열에 의해 더 높은 패가 결정된다.
포카드:네 장의 카드가 같은 값을 가지는 경우. 포카드끼리 맞붙는 경우에는 네 장의 같은 값을 가지는 카드의 값에 의해 더 높은 패가 결정된다.
스트레이트플러시: 다섯 장의 카드가 무늬가 같으면서 모두 연속적인 값을 가지는 경우. 패에 있는 것 중 가장 높은 카드에 의해 더 높은 패가 결정된다.
몇쌍의 포커 패를 비교해서 어느 ㅉ고이 이겼는지 아니면 무승부인지 알아내자.
입력:입력 파일은 여러 줄로 구성되며 각 줄에는 열 장의 카드를 나타내는 값이 들어간다. 앞에 있는 다섯 장의 카드는 "Black"이라는 참가자의 카드고, 뒤에 있는 다섯 장의 카드는"White"라는 참가자의 카드다.
출력 : 입력된 ㅏㄱㄱ 줄에 대해 다음 중 한 가지가 들어있는 행을 출력한다(첫번째는 Black이 이기는 경우, 두번째는 White가 이기는 경우, 세번째는 둘이 비기는 경우).
Black wins. White wins. Tie.
풀이 :먼저 포커 패의 등급을 비교할 수 있는 족보를 만들고, 주어진 black,white의 카드를 이 족보와 비교해 등급을 매기고, 서로 등급을 비교하여 결과를 출력한다.
소스코드
:#include <stdio.h>
#define CARD_NUM 5
//encode_card에서 숫자는 *10
#define get_value(x) ((x) / 10)
//encode_card에서 종류는 +1,2,3,4
#define get_suit(x) ((x) % 10)
int encode_card(char *card);
long get_hand_value(int hand[5]);
void main(void)
{
char line[100];
int hand[2][5]; //hand[Blakc,White][card_num]
long hand_value[2]; //Black, White
int i,j,t;
while(gets(line) && *line)
{
t=0;
for(i=0;i<2;i++) //Black, White
{
for(j=0;j<5;j++) //숫자
{
while(line[t] ==' ') //빈칸은 패스
t++;
hand[i][j] = encode_card(line+t); //hand[i][j]에 숫자 입력
t+=2; //숫자,종류(하트,스페이스....)
}
hand_value[i]=get_hand_value(hand[i]); //등급 매기기
}
if(hand_value[0] > hand_value[1]) // 검은색 카드의 등급이 더 높을 때
printf("Black wins.");
else if(hand_value[0] < hand_value[1])//흰색 카드의 등급이 더 높을 때
printf("White wins.");
else //비겼을 때
printf("Tie.");
}
}
int encode_card(char *card)
{
int result;
switch(card[0]) // 숫자
{
case 'T': result = 100; break;//10
case 'J': result = 110; break;//Jack
case 'Q': result = 120; break;//Queen
case 'K': result = 130; break;//King
case 'A': result = 140; break;//Ace
default: result = (card[0] - '0') * 10; //num
}
switch(card[1]) // 종류
{
case 'H': result+=1; break; //Heart
case 'D': result+=2; break; //Diamond
case 'S': result+=3; break; //Space
case 'C': result+=4; break; //Clober
}
return result;
}
//등급 매기는 함수
long get_hand_value(int hand[5])
{
int i,j,max,temp;
int value[5],suit[5]; // 값,종류
long result; // 결과
//직접 선택법으로 내림차순 정렬
for(i=0;i<4;i++)
{
max=i;
for(j=i+1;j<5;j++)
if(hand[j] > hand[max])
max = j;
temp = hand[i];
hand[i] = hand[max];
hand[max] = temp;
}
//정렬을 해 놓으면 등급 계산이 편리하다.
for(i=0;i<5;i++)
{
//값 저장
value[i] = get_value(hand[i]); // 전처리기 참조
suit[i] = get_suit(hand[i]); // 전처리기 참조
}
//straight flush
if(value[1]+1==value[0] && suit[1] == suit[0]
&& value[2]+2 == value[0] && suit[2] == suit[0]
&& value[3]+3 == value[0] && suit[3] == suit[0]
&& value[4]+4 == value[0] && suit[4] == suit[0])
result = (9 << 20)//등급 9개
+(value[0] << 16);
//four of a kind (1,4),(2,5)만 검사하면 된다
else if(value[0] == value[3] || value[1] == value[4])
result = (8<<20) + (value[1] << 16);
//full house 2+3,3+2를 검사한다.
else if(value[0] == value[2] && value[3] == value[4]) //3+2
result = ( 7<<20) + (value[0] << 16);
else if(value[0] == value[1] && value[2] == value[4]) //2+3
result = (7<<20) + (value[2] << 16);
//flush
else if(suit[1] == suit[0] && suit[2] == suit[0]
&& suit[3] == suit[0] && suit[4]==suit[0])
result = (6<<20) + (value[0] << 16) + (value[1] << 12)
+ (value[2] << 8) + (value[3] << 4) + value[4];
//straight
else if(value[1]+1 == value[0] && value[2]+2 == value[0]
&& value[3]+3==value[0] && value[4]+4==value[0])
result=(5<<20) + (value[0]<<16);
//three of a kind
else if(value[0] ==value[2] || value[1]==value[3]
|| value[2] == value[4])
result=(4<<20) + (value[2] << 16);//3번째 카드는 무조건 쓰리카드에 포함
//two pairs
else if(value[0]==value[1]&&value[2]==value[3])
result=(3<<20) + (value[1]<<16) + (value[3] << 12) + (value[4] << 8);
else if(value[0] == value[1] && value[3]==value[4])
result = (3<<20) + (value[1] << 16) + (value[3] << 12) + (value[2] << 8);
else if(value[1] == value[2] && value[3] == value[4])
result = (3<<20) + (value[1] << 16) + (value[3] << 12) + (value[0] << 8);
// pair
else if(value[0] ==value[1])
result = (2<<20) + (value[0]<<16) + (value[2]<<12) + (value[3]<<8) + (value[4]<<4);
else if(value[1]==value[2])
result = (2<<20) + (value[1]<<16) + (value[0]<<12) + (value[3]<<8) + (value[4]<<4);
else if(value[2]==value[3])
result = (2<<20) + (value[2]<<16) + (value[0]<<12) + (value[1]<<8) + (value[4]<<4);
else if(value[3]==value[4])
result=(2<<20) + (value[3]<<16) + (value[0]<<12) + (value[1]<<8) + (value[2]<<4);
//high card
else
result = (1<<20) + (value[0] << 16) + (value[1] << 12) + (value[2] << 8)
+ (value[3] << 4) + value[4];
return result;
}
'2009~2014 > C/C++' 카테고리의 다른 글
[C언어 기출문제&풀이] 쌓아 올리기(Stack 'em Up) (0) | 2011.05.15 |
---|---|
[C언어 기출문제&풀이] 동맹휴업(Hartal) (0) | 2011.05.15 |
[C언어 기출문제&풀이] 유쾌한 점퍼(jolly Jumpers) (0) | 2011.05.15 |
[C언어 기출문제&풀이] 후보식 투표법(Australian Voting) (0) | 2011.05.15 |
[C언어 기출문제&풀이] 체크확인 (Check the Check) (0) | 2011.05.14 |