UVa 131 有超能力的纸牌玩家

题意:题目描述太简单了,简直需要猜题目。看别人的题解也知道题目意思。大致意思是,手里五张牌,可以弃0~5张,然后从牌堆的5张中拿最上面的同等数量纸牌,使得value最大。value的评价真的是要猜。。。依次为:

straight-flush   同花顺
four-of-a-kind   炸弹
full-house      满堂红 三张同点牌加上一对 
flush       同花
straight   顺子(注意A即可接2也可以接K)
three-of-a-kind   三张相同的牌 
two-pairs   两对对子 
one-pair   一对对子 
highest-card     单张最大
思路:知道题目意思后就比较简单。枚举手里5张牌的所有子集,不够5张的,就从牌堆最上方拿来补足5张。然后用这5张来判断即可。由于这里只是5张,比较小,所以直接进行判断就可以了。之前想记录下5张中有几个5同、4同、3同、2同的,太麻烦了,直接依次从分值最大的开始判断即可。在得到5张牌之后,可以判断是否同色,排序后方便判断顺子以及对子等。

Code:

#include<stdio.h>
#include<stdlib.h>

void solve();
void subset(int *A, int cur);
int process(int cur);
int cmp_int(const void *_a, const void *_b);

char besthd[][22]={"straight-flush","four-of-a-kind","full-house","flush",
         "straight","three-of-a-kind","two-pairs","one-pair","highest-card"};
char cards[10][5];
int value[10];
int A[6];
int min;

int main()
{
  //freopen("131.in","r",stdin);
  //freopen("131.out","w",stdout);
    
  for(int i=0;i<10;++i)
  {
    if(scanf("%s",cards[i])!=1) break;
    if(i<9) continue;
    printf("Hand:");
    for(int j=0;j<5;++j)
      printf(" %s",cards[j]);
    printf(" Deck:");
    for(int j=5;j<10;++j)
      printf(" %s",cards[j]);
    printf(" Best hand: ");
    solve();
    i=-1;
  }
}

void solve()
{
  for(int i=0;i<10;++i)
  {
    if(cards[i][0]=='T') value[i]=10;
    else if(cards[i][0]=='J') value[i]=11;
    else if(cards[i][0]=='Q') value[i]=12;
    else if(cards[i][0]=='K') value[i]=13;
    else if(cards[i][0]=='A') value[i]=1;
    else value[i]=cards[i][0]-'0';      
  }
  min=8;
  subset(A,0);
  printf("%s\n",besthd[min]);
}

void subset(int *A, int cur)
{
  int temp=process(cur);
  min=temp<min?temp:min;

  int s=cur?A[cur-1]+1:0;
  for(int i=s;i<5;++i)
  {
    A[cur]=i;
    subset(A,cur+1);      
  }
}

int process(int cur)
{
  int num[5];
  int ts=1;//同色 
  for(int i=0;i<cur;++i)
  {
    num[i]=value[A[i]];
    if(cards[A[i]][1]!=cards[A[0]][1]) ts=0;
  }
  for(int i=cur;i<5;++i)
  {
    num[i]=value[5+i-cur];//是5,不是6 
    if(cards[5+i-cur][1]!=cards[A[0]][1]) ts=0;
  }
  
  qsort(num,5,sizeof(num[0]),cmp_int);
  
  int sz=1;//顺子  但1,10,11,12,13也是顺子 
  for(int i=0;i<4;++i)
  {
    if(i==0 && num[i]==1 && num[4]==13) continue;
    if(num[i]-num[i+1]!=-1) { sz=0; break;}
  }
  
  if(sz&&ts) return 0;
  if((num[0]==num[1] || num[3]==num[4]) && num[1]==num[2] && num[2]==num[3]) return 1;
  if(num[0]==num[1] && num[1]==num[2] && num[3]==num[4]) return 2;
  if(num[0]==num[1] && num[2]==num[3] && num[3]==num[4]) return 2;
  if(ts) return 3;
  if(sz) return 4;
  if(num[0]==num[1] && num[1]==num[2]) return 5;
  if(num[1]==num[2] && num[2]==num[3]) return 5;
  if(num[3]==num[4] && num[4]==num[5]) return 5;
  if(num[0]==num[1] && (num[2]==num[3]||num[3]==num[4])) return 6;
  if(num[1]==num[2] && num[3]==num[4]) return 6;
  if(num[0]==num[1] || num[1]==num[2] || num[2]==num[3] || num[3]==num[4]) return 7;
  else return 8;
}

int cmp_int(const void *_a, const void *_b)
{
  return *(int*)_a - *(int*)_b;  
}
Code2:

//非递归形式,即二进制法枚举子集 
#include<stdio.h>
#include<stdlib.h>

void solve();
void subset(int *A, int cur);
int process(int cur);
int cmp_int(const void *_a, const void *_b);

char besthd[][22]={"straight-flush","four-of-a-kind","full-house","flush",
         "straight","three-of-a-kind","two-pairs","one-pair","highest-card"};
char cards[10][5];
int value[10];
int A[6];
int min;

int main()
{
  freopen("131.in","r",stdin);
  freopen("131.out","w",stdout);
    
  for(int i=0;i<10;++i)
  {
    if(scanf("%s",cards[i])!=1) break;
    if(i<9) continue;
    printf("Hand:");
    for(int j=0;j<5;++j)
      printf(" %s",cards[j]);
    printf(" Deck:");
    for(int j=5;j<10;++j)
      printf(" %s",cards[j]);
    printf(" Best hand: ");
    solve();
    i=-1;
  }
}

void solve()
{
  for(int i=0;i<10;++i)
  {
    if(cards[i][0]=='T') value[i]=10;
    else if(cards[i][0]=='J') value[i]=11;
    else if(cards[i][0]=='Q') value[i]=12;
    else if(cards[i][0]=='K') value[i]=13;
    else if(cards[i][0]=='A') value[i]=1;
    else value[i]=cards[i][0]-'0';      
  }
  min=8;
  for(int i=0;i<(1<<5);++i)
  {  
    int cur=0;
    for(int j=0;j<5;++j)
      if(i & (1<<j))
      {
        A[cur++]=j;
      }    
    int temp=process(cur);
    min=temp<min?temp:min;
  }
  printf("%s\n",besthd[min]);
}

int process(int cur)
{
  int num[5];
  int ts=1;//同色 
  for(int i=0;i<cur;++i)
  {
    num[i]=value[A[i]];
    if(cards[A[i]][1]!=cards[A[0]][1]) ts=0;
  }
  for(int i=cur;i<5;++i)
  {
    num[i]=value[5+i-cur];//是5,不是6 
    if(cards[5+i-cur][1]!=cards[A[0]][1]) ts=0;
  }
  
  qsort(num,5,sizeof(num[0]),cmp_int);
  
  int sz=1;//顺子  但1,10,11,12,13也是顺子 
  for(int i=0;i<4;++i)
  {
    if(i==0 && num[i]==1 && num[4]==13) continue;
    if(num[i]-num[i+1]!=-1) { sz=0; break;}
  }
  
  if(sz&&ts) return 0;
  if((num[0]==num[1] || num[3]==num[4]) && num[1]==num[2] && num[2]==num[3]) return 1;
  if(num[0]==num[1] && num[1]==num[2] && num[3]==num[4]) return 2;
  if(num[0]==num[1] && num[2]==num[3] && num[3]==num[4]) return 2;
  if(ts) return 3;
  if(sz) return 4;
  if(num[0]==num[1] && num[1]==num[2]) return 5;
  if(num[1]==num[2] && num[2]==num[3]) return 5;
  if(num[3]==num[4] && num[4]==num[5]) return 5;
  if(num[0]==num[1] && (num[2]==num[3]||num[3]==num[4])) return 6;
  if(num[1]==num[2] && num[3]==num[4]) return 6;
  if(num[0]==num[1] || num[1]==num[2] || num[2]==num[3] || num[3]==num[4]) return 7;
  else return 8;
}

int cmp_int(const void *_a, const void *_b)
{
  return *(int*)_a - *(int*)_b;  
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值