Project Euler 54

题目如下:

In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way:

  • High Card: Highest value card.
  • One Pair: Two cards of the same value.
  • Two Pairs: Two different pairs.
  • Three of a Kind: Three cards of the same value.
  • Straight: All cards are consecutive values.
  • Flush: All cards of the same suit.
  • Full House: Three of a kind and a pair.
  • Four of a Kind: Four cards of the same value.
  • Straight Flush: All cards are consecutive values of same suit.
  • Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.

The cards are valued in the order:
2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.

If two players have the same ranked hands then the rank made up of the highest value wins; for example, a pair of eights beats a pair of fives (see example 1 below). But if two ranks tie, for example, both players have a pair of queens, then highest cards in each hand are compared (see example 4 below); if the highest cards tie then the next highest cards are compared, and so on.

Consider the following five hands dealt to two players:

Hand

 

Player 1

 

Player 2

 

Winner

1

 

5H 5C 6S 7S KD

Pair of Fives

 

2C 3S 8S 8D TD

Pair of Eights

 

Player 2

2

 

5D 8C 9S JS AC

Highest card Ace

 

2C 5C 7D 8S QH

Highest card Queen

 

Player 1

3

 

2D 9C AS AH AC

Three Aces

 

3D 6D 7D TD QD

Flush with Diamonds

 

Player 2

4

 

4D 6S 9H QH QC

Pair of Queens
Highest card Nine

 

3D 6D 7H QD QS

Pair of Queens
Highest card Seven

 

Player 1

5

 

2H 2D 4C 4D 4S

Full House
With Three Fours

 

3C 3D 3S 9S 9D

Full House
with Three Threes

 

Player 1

The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.

How many hands does Player 1 win?

贴上我的代码,代码不够简洁。

/*
*==================================================
*       FileName:   euler 54.cpp
*
*    Description:   扑克牌比较大小 
*   
*
*        Version:   1.0
*        Created:   2011年7月17日
*       Revision:   none
*       Complier:   vs 2008
*
*         Author:   Joney
*        Company:   ZJU
*===================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


/*排序函数*/
void Insertion(int* a, int p, int r);
void InsertSort(int* a,int p, int r);
/*大小函数*/
int RoyalFlush(int* an1, char* as1,int* an2, char* as2);
int StraightFlush(int* an1, char* as1,int* an2, char* as2);
int FourKind(int* an1, char* as1,int* an2, char* as2);
int FullHouse(int* an1, char* as1,int* an2, char* as2);
int Flush(int* an1, char* as1,int* an2, char* as2);
int Straight(int* an1, char* as1,int* an2, char* as2);
int ThreeKind(int* an1, char* as1,int* an2, char* as2);
int TwoPairs(int* an1,int* an2);
int OnePair(int* an1,int* an2);
int HighCard(int* an1,int* an2);
bool Same(char* a);
bool Consecutive(int* a);
int FourSame(int* a);
int FindFH(int* a);
int ThreeSame(int* a);
int TwoSame(int* a);
int OneSame(int* a);
int main(){
	double start=clock();
	FILE* fp;
	char a[31];    /*包括一个回车符*/
    char p1[15];
	char p2[15];
	int  an1[5],an2[5];
	char as1[5],as2[5];
	int count=0;
	int count2=0;
	int number=0;
	int flag;
	fp=fopen("poker.txt","r");
	if(!fp)
		return -1;
	while(fgets(a,31,fp)!=NULL){
		number++;
		for(int i=0;i<30;i++){
			if(i<15)
				p1[i]=a[i];
		    else
				p2[i-15]=a[i];
		}
		for(int i=0;i<15;i+=3){
			char temp=p1[i];
			switch(temp){
				case 'T': an1[i/3]=10;break;
				case 'J': an1[i/3]=11;break;
				case 'Q': an1[i/3]=12;break;
				case 'K': an1[i/3]=13;break;
				case 'A': an1[i/3]=14;break;				
				default:  an1[i/3]=p1[i]-'0';break;

			}
		}
		for(int i=1;i<15;i+=3)
			as1[i/3]=p1[i];
		for(int i=0;i<15;i+=3){
			char temp=p2[i];
			switch(temp){

				case 'T': an2[i/3]=10;break;
				case 'J': an2[i/3]=11;break;
				case 'Q': an2[i/3]=12;break;
				case 'K': an2[i/3]=13;break;
				case 'A': an2[i/3]=14;break;				
				default:  an2[i/3]=p2[i]-'0';break;

			}
		}
		for(int i=1;i<15;i+=3)
			as2[i/3]=p2[i];	
		InsertSort(an1,0,4);
		InsertSort(an2,0,4);
		/*牌开始比较大小*/
		if(flag=RoyalFlush(an1,as1,an2,as2)){
			if(flag==1)
			   count++;
			else 
			   count2++;
			continue;
		}
		if(flag=StraightFlush(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=FourKind(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=FullHouse(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=Flush(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=Straight(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=ThreeKind(an1,as1,an2,as2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=TwoPairs(an1,an2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=OnePair(an1,an2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}
		if(flag=HighCard(an1,an2)){
			if(flag==1)
				count++;
			else 
				count2++;
			continue;
		}

	}
	fclose(fp);
	printf("%d %d\n",count,count2);
	double end=clock();
	double time=(end-start)/1000;
	printf("used time is %fs\n",time);
	system("pause");

}

/*插入排序*/
void InsertSort(int* a,int p, int r){
	if(p<r){
		int q=r-1;
		InsertSort(a, p, q);
		Insertion(a, p, r);
	}
}

void Insertion(int* a, int p, int r){
	int key=a[r];
	int i=r-1;
	while(a[i]>key&&i>(p-1)){
		a[i+1]=a[i];
		i--;
	}
	a[i+1]=key;
}

bool Same(char* a){
	for(int i=0;i<4;i++)
		if(a[i]!=a[i+1])
			return false;
	return true;
}

bool Consecutive(int* a){
	for(int i=0;i<4;i++)
		if((a[i]+1)!=a[i+1])
			return false;
	return true;
}
int FourSame(int* a){
	if((a[0]==a[1])&&(a[1]==a[2])&&(a[2]==a[3]))
		return 1;
	else if((a[1]==a[2])&&(a[2]==a[3])&&(a[3]==a[4]))
		return 4;
	else
		return 0;
}

int FindFH(int* a){
	if(a[0]==a[1]&&a[2]==a[3]==a[4])
		return 14;
	else if(a[3]==a[4]&&a[0]==a[1]==a[2])
		return 42;
	else
		return 0;
}

int ThreeSame(int* a){
	if((a[0]==a[1])&&(a[1]==a[2]))
		return 2;
	else if((a[1]==a[2])&&(a[2]==a[3]))
		return 3;
	else if((a[2]==a[3])&&(a[3]==a[4]))
		return 4;
	else
		return 0;
}

int TwoSame(int* a){
	if(a[0]==a[1]&&a[2]==a[3])
		return 13;
	else if(a[0]==a[1]&&a[3]==a[4])
		return 14;
	else if(a[1]==a[2]&&a[3]==a[4])
		return 24;
	else
		return 0;
}

int OneSame(int* a){
	if(a[0]==a[1])
		return 1;
	else if(a[1]==a[2])
		return 2;
	else if(a[2]==a[3])
		return 3;
	else if(a[3]==a[4])
		return 4;
	else
		return 0;

}
int RoyalFlush(int* an1, char* as1,int* an2, char* as2){
	 if(an1[0]==10&&Same(as1)&&Consecutive(an1)&&(!Same(as2)||!Consecutive(an2)))
		 return 1;
	 else if(an2[0]==10&&Same(as2)&&Consecutive(an2)&&(!Same(as1)||!Consecutive(an1)))
		 return 2;
	 else
		 return 0;
}

int StraightFlush(int* an1, char* as1,int* an2, char* as2){
	if(Same(as1)&&Consecutive(an1)&&(!Same(as2)||!Consecutive(an2)))
		return 1;
	else if(Same(as2)&&Consecutive(an2)&&(!Same(as1)||!Consecutive(an1)))
		return 2;
	else if(Same(as1)&&Consecutive(an1)&&Same(as2)&&Consecutive(an2)){
		if(an1[4]>an2[4])
			return 1;
		else if(an1[4]<an2[4])
			return 2;
		else 
			return 0;
	}
	else
		return 0;

}

int FourKind(int* an1, char* as1,int* an2, char* as2){
	int site1,site2;
	if(FourSame(an1)&&!FourSame(an2))
		return 1;
	else if(FourSame(an2)&&!FourSame(an1))
		return 2;
	else if((site1=FourSame(an1))&&(site2=FourSame(an2))){
		if(an1[site1]>an2[site2])
			return 1;
		else if(an1[site1]<an2[site2])
			return 2;
		else
			return 0;
	}
	else 
		return 0;
}

int FullHouse(int* an1, char* as1,int* an2, char* as2){
	int site1,site2;
	if(FindFH(an1)&&!FindFH(an2))
		return 1;
	else if(FindFH(an2)&&!FindFH(an1))
		return 2;
	else if((site1=FindFH(an1))&&(site2=FindFH(an2))){
		if(an1[site1%10]>an2[site2%10])
			return 1;
		else if(an1[site1%10]<an2[site2%10])
			return 2;
		if(an1[site1/10]>an2[site2/10])
			return 1;
		else if(an1[site1/10]<an2[site2/10])
			return 2;
		else
			return 0;
	}
	else
		return 0;

}

int Flush(int* an1, char* as1,int* an2, char* as2){
	if(Same(as1)&&!Same(as2))
		return 1;
	else if(Same(as2)&&!Same(as1))
		return 2;
	else if(Same(as1)&&Same(as2)){
	    if(an1[4]>an2[4])
			return 1;
		else if(an1[4]<an2[4])
			return 2;
		else if(an1[3]>an2[3])
			return 1;
		else if(an1[3]<an2[3])
			return 2;
		else if(an1[2]>an2[2])
			return 1;
		else if(an1[2]<an2[2])
			return 2;
		else if(an1[1]>an2[1])
			return 1;
		else if(an1[1]<an2[1])
			return 2;
		else if(an1[0]>an2[0])
			return 1;
		else if(an1[0]<an2[0])
			return 2;
		else
			return 0;
	}
	else
		return 0;
}

int Straight(int* an1, char* as1,int* an2, char* as2){
	if(Consecutive(an1)&&!Consecutive(an2))
		return 1;
	else if(Consecutive(an2)&&!Consecutive(an1))
		return 2;
	else if(Consecutive(an1)&&Consecutive(an2)){
		if(an1[4]>an2[4])
			return 1;
		else
			return 2;
	}
	else
		return 0;

}

int ThreeKind(int* an1, char* as1,int* an2, char* as2){
	int site1=ThreeSame(an1),site2=ThreeSame(an2);
	if(site1&&(!site2))
		return 1;
	else if(site2&&(!site1))
		return 2;
	else if(site1&&site2){
		if(an1[site1]>an2[site2])
			return 1;
		else if(an1[site1]<an2[site2])
			return 2;
		else if(an1[4]>an2[4])
			return 1;
		else if(an1[4]<an2[4])
			return 2;
		else if(an1[3]>an2[3])
			return 1;
		else if(an1[3]<an2[3])
			return 2;
		else if(an1[2]>an2[2])
			return 1;
		else if(an1[2]<an2[2])
			return 2;
		else if(an1[1]>an2[1])
			return 1;
		else if(an1[1]<an2[1])
			return 2;
		else if(an1[0]>an2[0])
			return 1;
		else if(an1[0]<an2[0])
			return 2;
		else
			return 0;
	}
	else
		return 0;
}

int TwoPairs(int* an1,int* an2){
	int site1=TwoSame(an1),site2=TwoSame(an2);
	if(site1&&(!site2))
		return 1;
	else if(site2&&(!site1))
		return 2;
	else if(site1&&site2){
		if(an1[site1%10]>an2[site2%10])
			return 1;
		else if(an1[site1%10]<an2[site2%10])
			return 2;
		else if(an1[site1/10]>an2[site2/10])
			return 1;
		else if(an1[site1/10]<an2[site2/10])
			return 2;
	}
	else
		return 0;

}

int OnePair(int* an1,int* an2){
	int site1=OneSame(an1),site2=OneSame(an2);
	if(site1&&(!site2))
		return 1;
	else if(site2&&(!site1))
		return 2;
	else if(site1&&site2){
		if(an1[site1]>an2[site2])
			return 1;
		else if(an1[site1]<an2[site2])
			return 2;
		else 
			return 0;
	}
	else
		return 0;

}

int HighCard(int* an1, int* an2){
	if(an1[4]>an2[4])
		return 1;
	else if(an1[4]<an2[4])
		return 2; 
	else if(an1[3]>an2[3])
		return 1;
	else if(an1[3]<an2[3])
		return 2;
	else if(an1[2]>an2[2])
		return 1;
	else if(an1[2]<an2[2])
		return 2;
	else if(an1[1]>an2[1])
		return 1;
	else if(an1[1]<an2[1])
		return 2;
	else if(an1[0]>an2[0])
		return 1;
	else if(an1[0]<an2[0])
		return 2;
	else
		return 0;

}

posted on 2011-07-17 21:40  清墨  阅读(852)  评论(0)    收藏  举报