200悬赏加50追分求C/C++编程“单人纸牌”

-问题描述DoublePatience是一种单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上。每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和... - 问题描述
Double Patience是一种单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上。
每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走。如果最后所有纸牌都被取走,则游戏者就赢了,否则游戏者就输了。
George很热衷于玩这个游戏,但是一旦有时有多种选择的方法,George就不知道取哪一种好了,George会从中随机地选择一种走,例如:顶上的9张牌为KS, KH, KD, 9H, 8S, 8D, 7C, 7D,6H,显然有5种取法:(KS, KH), (KS, KD), (KH, KD), (8S, 8D), (7C, 7D),当然George取到每一种取法的概率都是1/5。
有一次,George的朋友Andrew告诉他,这样做是很愚蠢的,不过George不相信,他认为如此玩最后成功的概率是非常大的。请写一个程序帮助George证明他的结论:计算按照他的策略,最后胜利的概率。

- 输入数据
9行每行4组用空格分开的字串,每个字串两个字符,分别表示牌面和花色,按照从堆底到堆顶的顺序给出。

- 输出数据
一行,最后胜利的概率,精确到小数点后6位。

- 样例输入
AS 9S 6C KS
JC QH AC KH
7S QD JD KD
QS TS JS 9H
6D TD AD 8S
QC TH KC 8D
8C 9D TC 7C
9C 7H JH 7D
8H 6S AH 6H

- 样例输出
0.589314
展开
 我来答
lkjhggv
2009-10-04 · TA获得超过3063个赞
知道大有可为答主
回答量:1550
采纳率:66%
帮助的人:1294万
展开全部

递归程序执行效率就是低哦,运行了5分钟才出结果

首先说明一下,为了简化问题,把花色条件去掉了(没用),扑克牌A-T用整型1-14代替,不用输入,直接在主函数中初始化(要自己输入的话很好做的)

程序如下(C语言):

有疑问百度HI,QQ406344627都可以。

main()

{float george(int data[][],int top[]);

int top[9],i,data[9][4]={

              { 1, 9, 6,13},

              {11,12, 1,13},

              { 7,12,11,13},

              {12,14,11, 9},

              { 6,14, 1, 8},

              {12,14,13, 8},

              { 8, 9,14, 7},

              { 9, 7,11, 7},

              { 8, 6, 1, 6}};

float p;

 for(i=0;i<9;i++)

  top[i]=3;

/*top数组记录每一堆最上面的位置,如3表示此堆没拿走一张,-1表示已经拿完了*/

p=george(data,top);

printf("%f",p);

getch();

}

float george(int data[9][4],int top[9])

{int k=0,s=0,i,j;

 float p0=0;

 for(i=0;i<9;i++)

 for(j=i+1;j<9;j++)

   if(top[i]>=0&&top[j]>=0)

   if(data[i][top[i]]==data[j][top[j]])

    k++;

/*k表示可能走的方法数*/

 for(i=0;i<9;i++)if(top[i]>=0)s=1;

 if(k==0&&s==1)return 0;

/*k=0,s=1表示无路可走,但是牌没拿完,证明是失败的走法,成功概率为0*/

 if(k==0&&s==0)return 1;

/*牌拿完了*/

 for(i=0;i<9;i++)

 for(j=i+1;j<9;j++)

   if(top[i]>=0&&top[j]>=0)

   if(data[i][top[i]]==data[j][top[j]])

   {top[i]--;top[j]--;p0+=george(data,top)/k;top[i]++;top[j]++;}

/*把经过下一步(每个方向的成功概率)/k表示经过此步成功的概率k为此步后的拿取方法*/

return p0;

}

wangtk1982
2009-10-04 · TA获得超过3742个赞
知道大有可为答主
回答量:3206
采纳率:100%
帮助的人:1416万
展开全部
MARK~
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
georangel
2009-10-04 · TA获得超过541个赞
知道小有建树答主
回答量:319
采纳率:0%
帮助的人:358万
展开全部
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TIMES 1e3

typedef struct ST_CARD{
char exist;
char sign[3];
} card;

typedef struct ST_DupT{
int c;
char rown[4]; // max 4 types,record their rown this time
} DupT;

char nums[10] = "6789TJQKA";
char types[5] = "HDCS";
float possi_num = 0;
float impossi_num = 0;

void no_choice_cards(int nG,card cards[]){
// nG == 1 || nG == 0
int i,j;
int pos;

srand(time(0)); /* seed for rand */
for(i=0; i<36; i++){
cards[i].exist = '\0';
}

for(i=0; i<9; i++){
for(j=0; j<nG; j++){
pos = i*4 + j;
cards[pos].sign[0] = nums[i];
cards[pos].sign[1] = types[j];
cards[pos].sign[2] = '\0';
cards[pos].exist = i+'0';
}
}

for(i=0; i<9; i++){
for(j=nG; j<4; j++){
/* find a card's position */
pos = rand()%36;
while('\0' != cards[pos].exist){ /* while exist */
++pos;
if(36 == pos){
pos = 0;
} /* if */
} /* while */

cards[pos].sign[0] = nums[i]; /* not null */
cards[pos].sign[1] = types[j];
cards[pos].sign[2] = '\0';
cards[pos].exist = i+'0';
/* printf("%c+%c(%d)\t",cards[pos].sign[0],cards[pos].sign[1],pos); */
}
}
}

void display(card cards[]){
int x,y;
for(y=0; y<9; y++){
for(x=0; x<4; x++){
printf("%s\t",cards[y*4+x].sign);
}
printf("\n");
}
}

int possi(card cards[],char coln[],char sequence[],float possiblit){
/* do not take it seriously, please */
int i;
int m,n;

int x,y;
int idx;
int possible;
int bLeaf;
float fPossi;
int m_col,n_col;
int m_row,n_row;
int c_col = 0;
char seqb[73] = "\0";
DupT dup[9] = {{0,"\0\0\0"},{0,"\0\0\0"},{0,"\0\0\0"},
{0,"\0\0\0"},{0,"\0\0\0"},{0,"\0\0\0"},
{0,"\0\0\0"},{0,"\0\0\0"},{0,"\0\0\0"}};
char colnb[10] = "000000000"; //coln : next top card's col number
char choice[2] = "n";

// at least 2 rows, their col number do not over. if not, return 0
// count above cols

for(i=0; i<9; i++){
if(coln[i]<='3'){
++c_col;
idx = cards[i*4 + coln[i]-'0'].exist - '0'; // 6789TJQKA and 012345678
dup[idx].rown[dup[idx].c] = '0' + i; // record i : top card(i row)
dup[idx].c += 1;
}
}

if(c_col < 2){
impossi_num += 1;
printf("%f(impossible)\t\t%f(possible)\n",impossi_num,possi_num);
if(impossi_num >= MAX_TIMES){
printf("sorry, stop now\n");
display(cards);
printf("possiblity:%f\n",possi_num/(impossi_num+possi_num+0.000001));
exit(0);
}
return 0;
}

/* calculate the possiblity, and accumulate them, want correct
for(i=0; i<9; i++){
if(dup[i].c >= 2){
fPossi += ((dup[i].c)*(dup[i].c-1))/2;
}
}

fPossi /= (c_col*(c_col-1))/2;
fPossi *= possiblity;
*/

possible = 0;
bLeaf = 1; // assume : the end of tree, be leaf
for(i=0; i<9; i++){
if(dup[i].c >= 2){
// exist match event, if it can not enter into this branch before i == 9, return 0
// only if (2 == c_col && m_col == (int)'4' && n_col == (int)'4'), return 1
bLeaf = 0; // have sub tree

for(m=0; m<dup[i].c-1; m++){
for(n=m+1; n<dup[i].c; n++){
strcpy(colnb,coln); // backup coln

/*
printf("\nbefore selecting:\n");
for(y=0; y<9; y++){
for(x=0; x<4; x++){
if(x<(coln[y]-'0')) printf(" \t");
else printf("%s\t",cards[y*4+x].sign);
}
printf("\n");
}
*/

// 48 == (int)'0'
m_row = dup[i].rown[m] - '0';
n_row = dup[i].rown[n] - '0';
m_col = (++coln[m_row]) - '0';
n_col = (++coln[n_row]) - '0';

/* watch the process
printf("possiblity: %f, selected: %s(%d,%d),%s(%d,%d)\n",fPossi,cards[m_row*4+m_col-1].sign,m_row+1,m_col,
cards[n_row*4+n_col-1].sign,n_row+1,n_col);
printf("after selecting:\n");
for(y=0; y<9; y++){
for(x=0; x<4; x++){
if(x<(coln[y]-'0')) printf(" \t");
else printf("%s\t",cards[y*4+x].sign);
}
printf("\n");
}
while('y' != choice[0]){
printf("continue? y/n :");
scanf("%s",choice);
if('n' == choice[0]) exit(0);
}
*/
strcpy(seqb,sequence); // backup
strcat(sequence,cards[m_row*4+m_col-1].sign);
strcat(sequence,cards[n_row*4+n_col-1].sign);

if(2 == c_col && m_col == 4 && n_col == 4){
possi_num += 1; // leaves, count
printf("%f(impossible)\t\t%f(possible)\n",impossi_num,possi_num);
//printf("%s\n",sequence);
if(possi_num >= MAX_TIMES){
printf("sorry, stop now\n");
display(cards);
printf("possiblity:%f\n",possi_num/(impossi_num+possi_num+0.000001));
exit(0);
}
return 1;
}

if(possi(cards,coln,sequence,fPossi)) possible = 1;

strcpy(sequence,seqb); // recover
strcpy(coln,colnb); // end and restart revoke
}
}
}
}
if(possible) return 1;
else {
if(bLeaf){
impossi_num += 1;
printf("%f(impossible)\t\t%f(possible)\n",impossi_num,possi_num);
if(impossi_num >= MAX_TIMES){
printf("sorry, stop now\n");
display(cards);
printf("possiblity:%f\n",possi_num/(impossi_num+possi_num+0.000001));
exit(0);
}
}
return 0;
}
}

// http://zhidao.baidu.com/question/119843681.html
int main(){
int i,j;
int all_possi;
char sequence[73] = "\0";
char coln[10] = "000000000";
/* input here */
card cards[36]; /* 9*4 */

no_choice_cards(0,cards);

possi(cards,coln,sequence,1);

/* display random cards as follow */
display(cards);

printf("possiblity:%f\n",possi_num/(impossi_num+possi_num+0.000001));

return 1;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式