A 牛牛
Time Limit:1000MS Memory Limit:65535K
题型: 编程题 语言: 无限制
描述
最近hl看到舍友在回顾星爷,发哥,瓦仔的《赌..》系列电影,然后就跟他们玩起扑克来。扑克里面有一种简单的玩法,叫做“牛牛”. 众所周知,一副扑克除去大小王之后剩下52张。2~9,T(相当于牌10),J,Q,K(J,Q,K的值相当于牌10),A(A作用相当于1) 各 4 张,牛牛的游戏 规则是,“庄家”先给每人派5张牌(包括自己,庄以外的玩家称为“闲家”)。 基本牌型: 1.没牛:5张牌中的任意3张加起来不能成为10的倍数。 2.有牛:5张牌中的存在3张加起来为10的倍数(称为牛),但另外2张不为10的倍数( C=(A+B)%10 , 则称为牛C ) 。 3.牛牛:5张牌中的存在3张加起来为10的倍数,且另外2张也为10的倍数。 4.五花:5张牌全为花(J,Q,K称为花,如Q,J,J,Q,K)。 大小比较: 1.牌型: 五花 > 牛牛 > 有牛(C越大牛越大) > 没牛 。 2.单张:A > K > Q > J > T > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2 。 牌型相同再比较单张。 玩法如下: 闲家每个回合可以向庄家投注,开牌后庄家的牌 >= 闲家的牌的时候,算作庄家赢。 赔率: 五花(1:4),牛牛(1:3),牛9(1:2),其他 (1:1)。 这个时候,轮到了hl做庄,他是星爷的传人,继承了星爷的超能力。 第一个超能力是透视,他能够看到所有闲家是什么牌。 第二个超能力是变牌,他能够使自己底牌变成自己想要的牌。 现在hl已经知道闲家拿着什么牌,闲家也知道hl已经开出来的4张牌, 当然闲家们足够聪明,会把自己的牌尽量大地表示出来。 hl要把底牌变成什么才能让自己赢得最多呢?
输入格式
第1行输入n( 0 < n < 9 ),表示闲家的数量。 第2行输入hl的4张牌。 第 3 ~ n + 3 行,每行分别输入闲家的5张牌还有他们下注的钱Wi( 0 < Wi <= 1000 )。
输出格式
输出一个值,表示hl能赢得最大钱数。 如果hl不能赢钱的话输出 impossible 。
输入样例
1 A9Q8 AAA99 1
输出样例
3
Hint
注意题目改了,没牛的赔率也是1赔1的
单case
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,h1number=0,i,j,k,l,flag=0,flag2=0,t,win=0;//h1number代表h1牛分
scanf("%d",&n);
getchar();
char h1pai[6];//庄家的牌!
scanf("%s",h1pai);
int playernumber[10]={0},h1painum[5],money[10],playnum[5];
char player[n][6];
int maxh1=0,maxplayer[10]={0},number[14]={0},temp=0;
for(i=0;i<n;i++)//输入玩家的牌和下注的钱
{
scanf("%s",player[i]);
scanf("%d",&money[i]);
}
//统计每种牌出现次数(4种花色)
for(i=0;i<4;i++)
{
if(h1pai[i]=='A')
number[1]++;
else if(h1pai[i]=='T')
number[10]++;
else if(h1pai[i]=='J')
number[11]++;
else if(h1pai[i]=='Q')
number[12]++;
else if(h1pai[i]=='K')
number[13]++;
else if(h1pai[i]!='\0')
{
t=h1pai[i]-'0';
number[t]++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<5;j++)
{
if(player[i][j]=='A')
number[1]++;
else if(player[i][j]=='T')
number[10]++;
else if(player[i][j]=='J')
number[11]++;
else if(player[i][j]=='K')
number[13]++;
else if(player[i][j]=='Q')
number[12]++;
else if(player[i][j]!='\0')
{
t=player[i][j]-'0';
number[t]++;
}
}
}
for(i=0;i<4;i++)//把庄家的4张牌的值都存到数组h1painum中,其中jkq都为100
{
if(h1pai[i]=='J'||h1pai[i]=='K'||h1pai[i]=='Q')
h1painum[i]=100;
else if(h1pai[i]=='T')
h1painum[i]=10;
else if(h1pai[i]=='A')
h1painum[i]=1;
else h1painum[i]=h1pai[i]-'0';
}
for(i=0;i<4;i++)//判断庄家的4张牌能否构成牛!
{
for(j=i+1;j<4;j++)
{
for(k=j+1;k<4;k++)
{
if((h1painum[i]+h1painum[j]+h1painum[k])%10==0)
{
flag=1;
}
}
}
}
//下面对三种h1四张牌情况的分析!
if(flag==1)//可以构成牛牛!
{
for(i=1;i<=13;i++)
{
if(number[i]<4&&number[i]>=0)
{
if(i>=11)
temp=10;
else temp=i;
t=(h1painum[0]+h1painum[1]+h1painum[2]+h1painum[3]+temp)%10;
if(t>h1number)
{
h1number=t;
if(i==1)
h1pai[4]='A';
else if(i==10)
h1pai[4]='T';
else if(i==11)
h1pai[4]='J';
else if(i==12)
h1pai[4]='Q';
else if(i==13)
h1pai[4]='K';
else
{
h1pai[4]=i+'0';
}
}
else if(t==0)
{
if(i==11||i==12||i==13)
{
h1painum[4]=100;
}
else h1painum[4]=i;
if(h1painum[0]+h1painum[1]+h1painum[2]+h1painum[3]+h1painum[4]==500)
h1number=100;
else
h1number=10;
}
}
}
}
int addpai;
if(flag==0)//那4张无法构成牛,此时尽可能使他的牛点数最大!
{
for(addpai=1;addpai<=13;addpai++)
{
if(number[addpai]<4&&number[addpai]>=0)
{
t=0;
if(addpai<=10)
h1painum[4]=addpai;
else h1painum[4]=10;
for(i=0;i<=4;i++)
{
for(j=i+1;j<=4;j++)
{
for(k=j+1;k<=4;k++)
{
if((h1painum[i]+h1painum[j]+h1painum[k])%10==0)
{
t=(h1painum[0]+h1painum[1]+h1painum[2]+h1painum[3]+h1painum[4])%10;
if(t>h1number)
{
h1number=t;
if(addpai==1)
h1pai[4]='A';
else if(addpai==10)
h1pai[4]='T';
else if(addpai==11)
h1pai[4]='J';
else if(addpai==12)
h1pai[4]='Q';
else if(addpai==13)
h1pai[4]='K';
else
{
h1pai[4]=addpai+'0';
}
}
else if(t==0)
h1number=10;
flag2=1;
}
}
}
}
if(t>h1number)
h1number=t;
}
}
if(flag2==0)
{
if(number[1]<=3&&number[1]>=0)
h1pai[4]='A';
else
for(i=13;i>=2;i--)
{
if(number[i]<=3)
{
if(i==13)
h1pai[4]='K';
else if(i==12)
h1pai[4]='Q';
else if(i==11)
h1pai[4]='J';
else if(i==10)
h1pai[4]='T';
else
h1pai[4]=i+'0';
break;
}
}
}
}
//下面将所有玩家的牛分存到playernumber数组中
for(i=0;i<n;i++)
{
for(j=0;j<5;j++)
{
if(player[i][j]=='J'||player[i][j]=='K'||player[i][j]=='Q')
playnum[j]=100;
else if(player[i][j]=='T')
playnum[j]=10;
else if(player[i][j]=='A')
playnum[j]=1;
else playnum[j]=player[i][j]-'0';
}
for(j=0;j<=4;j++)
{
for(k=j+1;k<=4;k++)
{
for(l=k+1;l<=4;l++)
{
if((playnum[j]+playnum[k]+playnum[l])%10==0)
{
if((playnum[0]+playnum[1]+playnum[2]+playnum[3]+playnum[4])==500)
playernumber[i]=100;
else if((playnum[0]+playnum[1]+playnum[2]+playnum[3]+playnum[4])%10!=0)
playernumber[i]=(playnum[0]+playnum[1]+playnum[2]+playnum[3]+playnum[4])%10;
else if((playnum[0]+playnum[1]+playnum[2]+playnum[3]+playnum[4])%10==0)
playernumber[i]=10;
}
}
}
}
}
t=0;
//下面将庄家闲家最大的牌存起来
for(i=0;i<5;i++)
{
if(h1pai[i]=='A')
t=14;
else if(h1pai[i]=='K')
t=13;
else if(h1pai[i]=='Q')
t=12;
else if(h1pai[i]=='J')
t=11;
else if(h1pai[i]=='T')
t=10;
else
t=h1pai[i]-'0';
if(t>maxh1)
maxh1=t;
}
for(i=0;i<n;i++)
{
t=0;
maxplayer[i]=0;
for(j=0;j<5;j++)
{
if(player[i][j]=='A')
t=14;
else if(player[i][j]=='K')
t=13;
else if(player[i][j]=='Q')
t=12;
else if(player[i][j]=='J')
t=11;
else if(player[i][j]=='T')
t=10;
else
t=player[i][j]-'0';
if(t>maxplayer[i])
maxplayer[i]=t;
}
}
for(i=0;i<n;i++)
{
if(h1number>playernumber[i]||(h1number==playernumber[i]&&maxh1>=maxplayer[i]))
{
if(h1number==9)
win+=money[i]*2;
else if(h1number==100)
win+=money[i]*4;
else if(h1number==10)
win+=money[i]*3;
else win+=money[i];
}
else if(h1number<playernumber[i]||(h1number==playernumber[i]&& maxh1<maxplayer[i]))
{
if(playernumber[i]==9)
win-=money[i]*2;
else if(playernumber[i]==100)
win-=money[i]*4;
else if(playernumber[i]==10)
win-=money[i]*3;
else win-=money[i];
}
}
if(win>0)
printf("%d",win);
else printf("impossible");
return 0;
}
思路:(顺便说一句,代码写得有点乱,也是第一次写那么长的代码,三百行,算是自己的里程碑吧),这道题目不难,就是有点繁琐。
我们先从hl的4张牌入手,分析他的四张牌是否可以有牛:
1.如果没牛,那么我们尽量要使变出来的牌有牛并且牛最大,如果仍然没牛,那么就加上最大的那张牌(A>K>Q>J...),这时候牌最大;
2.如果有牛:我们就变一个牌使得它是牛牛或者五花或者...,反正就是使得它牛最大。
注意事项:
1.我们要特别注意牌数有限,每张牌都有4个花色(当然题目不考虑花色的问题),我们必须把每种牌的数量记录下来;
2.变牌的时候我们要从剩余的牌中变,不能凭空变;
3.如果要变的牌是10(T,J,Q,K)的一个,那么我们优先考虑变K>Q>J>T。