Week9 homework-B-Dongdongxue playing cards

topic

Recently, Dongdong is addicted to playing cards. So he found HRZ, ZJM and others to play cards with him. Due to the large number of people, Dongdong slightly revised the rules of the game:

All playing cards are only counted by numbers, ignoring suits.
The size of each playing card is represented by a value. A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K refer to 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13.
Each player draws 5 playing cards to form a hand! (The number of cards of each type is unlimited, don’t worry, Dongdong’s family has countless decks of cards)

Of course, there are different types of cards in a hand, and there are big and small.
For example, now Dongdong's "hand of cards" (denoted as α) and Ruishen's "hand of cards" (denoted as β), either α> β, or α <β, or α = β.
So how do these two "hands" compare? First of all, for a hand of different types, the value is the label below; for a hand of the same type, the value is different according to the 5 cards that make up the hand. The following are the rules for the formation of this hand:

Big card: This hand does not meet any of the following formation rules. If α and β are both big cards, then define their size as the sum of the five cards that make up the hand.
Pair: 2 out of 5 cards have the same value. If both α and β are pairs, compare the size of this "pair". If the size of the "pairs" of α and β are equal, then compare the sum of the remaining 3 cards.
Two pairs: There are two different pairs of 5 cards. If both α and β are two pairs, first compare the larger pair of both parties. If they are equal, compare the smaller pair of both parties. If they are equal, only the last of the 5 cards can be compared. Pair of cards.
Three: 3 out of 5 cards have the same value. If α and β are both "three", compare the size of the "three", if the "three" of α and β are equal, then compare the sum of the remaining 2 cards.
Three with two: 3 of the 5 cards have the same value, and the other 2 cards have the same value. If α and β are both "three with two", first compare the size of their "three", if they are equal, then compare the size of the "pair".
Bomb: 4 of 5 cards have the same value. If α and β are both "bombs", compare the size of the "bombs", if they are equal, compare the size of the remaining card.
Straight: x, x+1, x+2, x+3, x+4 are formed from 5 cards. If both α and β are "straights", directly compare the maximum of the two straights.
Long Shun: The 5 cards are 10, J, Q, K, A.

As a competent magician, Dongdong learned about the 5 cards in the hands of the audience. He now wants to output a leaderboard. The ranking is sorted according to the size of the players' "hands". If two players have the same cards, then the names of the players are ranked first in the dictionary.
Unexpectedly, a beam of cosmic rays swept past at this time. In order to avoid cosmic rays, Dongdong emptied the Cache in his mind in a panic. Please tell Dongdong, the ranking of the audience

enter

The input contains multiple sets of data. Enter an integer n (1 <= n <= 1e5) at the beginning of each group, indicating how many people are in the audience.

Then there are n rows, each with a string s1 and s2 (1 <= |s1|,|s2| <= 10), s1 is the name of the corresponding person, and s2 is the card situation in his hand.

Output

For each set of test data, output n rows, which is the ranking of the audience this time. Sample input 3

DongDong AAA109

ZJM 678 910

Hrz 678910

Sample output

Hrz

ZJM

DongDong

Ideas

data structure

int cnt[14]:存储每个成员手里的牌牌面数字的个数
int num[5]:存储成员中单张牌的牌面数字
int num_cnt[6]:存储成员不同个数牌的个数
struct player:存储每个成员的姓名、牌、牌的类型、牌中呈对、三张、四张的牌的牌面的数字和手中牌面数字之和
{
    
    
 char name[20];
// string name;
 int pai[5];
 int type;
 int duizi[2]={
    
    0,0};
 int sum; 
 bool operator<(const player &p) const 
 重载比较符,先比较type,在type相等时,再按顺序比较存储在duizi中的数
 其中当为两对的情况时,duizi[0]存储两对中较大的,duizi[1]中存储为两对中较小的
 当为三代二:duizi[0]3个的数字,duizi[1]2个的数字
 当为三个和炸弹时:duizi[0]存储三个或四个的数字,duizi[1]=0
 在其他情况时:duizi[0/1]=0
 当duizi都相等时,根据题意的各个比较都可以转化为比较所有牌面总和
 当牌面总和也相等时,说明两个player手中的牌相同,所以直接比较名字的字典序即可得到排名
 {
    
    
  if(type!=p.type)
   return type>p.type;
  if(duizi[0]!=p.duizi[0])
   return duizi[0]>p.duizi[0];
  if(duizi[1]!=p.duizi[1])
   return duizi[1]>p.duizi[1];
  if(sum!=p.sum)
   return sum>p.sum;
  //为啥反了???? 
  int l1=strlen(name),l2=strlen(p.name);
  for(int j=0;j<min(l1,l2);j++)
  {
    
    
   if(name[j]==p.name[j]) continue;
   if(name[j]<p.name[j]) return true;
   if(name[j]>p.name[j]) return false;
  }
  if(l1<l2) return true;
  return false;
//  return name<p.name; 
 } 
}p[maxn]

solution

1. For each new player, first initialize all the content in p[i] corresponding to the player, then enter the name into the name, the card face into the temporary string container, and process it into a number and store it in p , Calculate the number of each card face and store it in cnt at the same time.
2. Traverse the cnt array from small to large, calculate the number of different numbers and store it in num_cnt, store a single card in num, and store it in num. Cnt update type
3. Determine whether the card is a straight or long-shun and update the type
4. Call sort, sort from big to small and output according to ranking.

error

1. Who could think of the brain-dead mistake of thinking Long Shun as five consecutive cards starting from 10, I can adjust it for a week? ? ? orz
2. Note that when using char[20] to store the name, the ordering of HRZ and ZJM will be reversed when calling return name<p.name, so consider implementing the lexicographic comparison yourself, as follows:

  //为啥反了???? 
  int l1=strlen(name),l2=strlen(p.name);
  for(int j=0;j<min(l1,l2);j++)
  {
    
    
   if(name[j]==p.name[j]) continue;
   if(name[j]<p.name[j]) return true;
   if(name[j]>p.name[j]) return false;
  }
  if(l1<l2) return true;
  return false;
//  return name<p.name; 
 } 
}p[maxn]

But when the name is stored in the string type, the return name<p.name gets the name sorted in lexicographical order.
3. At first, I forgot to set the new set of data duizi to a null value.
4. Pay attention to the card that judges the member. The type of the card is set to 1 before the card type, and then the card type is updated only when the card is a higher level. The case where
all five cards are equal is also a bomb

Code

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;
const int maxn=1e5+10;
const int maxm=20;
int cnt[14];
int num[5];
int num_cnt[6];
int tmp_sum=0;
struct player
{
    
    
	char name[20];
//	string name;
	int pai[5];
	int type;
	int duizi[2]={
    
    0,0};
	int sum;	
	bool operator<(const player &p) const
	{
    
    
		if(type!=p.type)
			return type>p.type;
		if(duizi[0]!=p.duizi[0])
			return duizi[0]>p.duizi[0];
		if(duizi[1]!=p.duizi[1])
			return duizi[1]>p.duizi[1];
		if(sum!=p.sum)
			return sum>p.sum;
		//为啥反了????	
		int l1=strlen(name),l2=strlen(p.name);
		for(int j=0;j<min(l1,l2);j++)
		{
    
    
			if(name[j]==p.name[j]) continue;
			if(name[j]<p.name[j]) return true;
			if(name[j]>p.name[j]) return false;
		}
		if(l1<l2) return true;
		return false;
//		return name<p.name; 
	}	
}p[maxn];
int main()
{
    
    
	int n;
	char temp_pai[20];
	while(scanf("%d",&n)!=EOF)
	{
    
    	
		for(int i=0;i<n;i++)//i为第i个人的牌 
		{
    
    
			cin>>p[i].name;
			cin>>temp_pai;
			p[i].duizi[0]=0;//注意每次需将p中所有的值置为初值 
			p[i].duizi[1]=0;
			int j=0;
			int m=0;//初始化 
			p[i].sum=0;//初始化 
			memset(cnt,0,sizeof(cnt));
			
			while(temp_pai[j]!='\0')
			{
    
    
				if(temp_pai[j]=='A')
				{
    
    
					p[i].pai[m]=1;
					p[i].sum+=1;
					cnt[1]++;					
				}
				else if(temp_pai[j]=='J')
				{
    
    
					p[i].pai[m]=11;
					p[i].sum+=11;//直接更新该player的sum 
					cnt[11]++;					
				}
				else if(temp_pai[j]=='Q')
				{
    
    
					p[i].pai[m]=12;	
					p[i].sum+=12;
					cnt[12]++;				
				}
				else if(temp_pai[j]=='K')
				{
    
    
					p[i].pai[m]=13;	
					p[i].sum+=13;
					cnt[13]++;				
				}
				else if(temp_pai[j]=='1')
				{
    
    
					p[i].pai[m]=10;
					p[i].sum+=10;
					cnt[10]++;
					j++;
				}
				else
				{
    
    
					int tmp=temp_pai[j]-'0';
					p[i].pai[m]=tmp;
					p[i].sum+=tmp;
					cnt[tmp]++;				
				}
				j++;
				m++;
			}
			m=0;//单张牌的个数 
			int x=0;//对子的个数 
			memset(num,0,sizeof(num));//存储仅有一张的牌 
			memset(num_cnt,0,sizeof(num_cnt));
//			cout<<"cnt:"<<endl;
//			for(j=0;j<14;j++)
//				cout<<cnt[j]<<' ';
//			cout<<endl;			
			p[i].type=1;//将初始情况置为1,因为后面可能出现五张牌都相等的情况 
			for(j=1;j<=13;j++)
			{
    
    
				if(cnt[j]==1)
				{
    
    
					num_cnt[1]++;
					num[m]=j;
					m++;
				}
				else if(cnt[j]==2)
				{
    
    
					num_cnt[2]++;
					if(x==1)
					{
    
    
						if(num_cnt[2]==2)//注意这里num_cnt已经加一了,故要判断是否==2 
						{
    
    
						p[i].duizi[1]=p[i].duizi[0];
						p[i].duizi[0]=j;
						p[i].type=3;						
						}
						else if(num_cnt[3]==1)
						{
    
    
							p[i].duizi[x]=j;
							p[i].type=5;
						}
						x++;
					}
					else
					{
    
    
					p[i].duizi[x]=j;
					p[i].type=2;						
					}
					x++; 			
				}
				else if(cnt[j]==3)
				{
    
    
					num_cnt[3]++;
					if(x==1)
					{
    
    
						p[i].duizi[1]=p[i].duizi[0];
						p[i].duizi[0]=j;
						p[i].type=5;
					}
					else
					{
    
    
						p[i].duizi[x]=j;
						p[i].type=4;						
					} 
					x++; 
				}
				else if(cnt[j]==4||cnt[j]==5)//注意当五张牌都相等时,也是炸弹 
				{
    
    
					num_cnt[4]++;
					p[i].duizi[x]=j;
					p[i].type=6;
					x++;
				}	
			}
//			cout<<"num_cnt:"<<endl;
//			for(j=0;j<6;j++)
//				cout<<num_cnt[j]<<' ';
//			cout<<endl;
//			cout<<"num:"<<endl;
//			for(j=0;j<5;j++)
//				cout<<num[j]<<' ';
//			cout<<endl;
				
			if(num_cnt[1]==5)
			{
    
    
				int flag=0;
				for(j=0;j<4;j++)
					if(num[j]!=num[j+1]-1)
						flag=1;
				if(flag==0)
				{
    
    
					p[i].type=7;					
				}
				else if(num[0]==1&&num[1]==10&&num[2]==11&&num[3]==12&&num[4]==13)//注意龙顺是10、j、q、k、a 
					p[i].type=8;
			}	
		}
		sort(p,p+n);
		for(int i=0;i<n;i++)
		{
    
    
			cout<<p[i].name<<endl;	
//			for(int j=0;j<5;j++)
//				cout<<p[i].pai[j];
//			cout<<p[i].type<<' '<<p[i].duizi[0]<<' '<<p[i].duizi[1]<<' '<<p[i].sum;
//			cout<<endl;		
		}

	}
	return 0;
}

Guess you like

Origin blog.csdn.net/alicemh/article/details/105614666