完美洗牌

题目:

洗之前不是乱牌,而是已经按顺序排好的(一般新牌打开就是这样)

完美洗牌8次后,顺序又回到了最初未洗之前!

code:
.h

 

public:
int* m_npValue;
int m_nAllNum; // 总牌数
void InitNum();
BOOL OperCheck(int* pNew); // 检验是否回到初始状态
void OperShuffle(int &nCount); // 洗牌
void OperMakeLog(int* pTemp,int nNum);


.cpp

 

void CAnswer1Dlg::OnButton1()
{
int nCount =0;
InitNum();
OperShuffle(nCount);
CString sTemp;
sTemp.Format("%d",nCount);
SetDlgItemText(IDC_STATIC_ANSWER,sTemp);
}
void CAnswer1Dlg::InitNum()
{
CString sTemp;
GetDlgItemText(IDC_EDIT1,sTemp);
m_nAllNum = atoi(sTemp); // 总牌数
if(m_nAllNum > 0)
{
if(m_npValue)
delete[] m_npValue;
m_npValue = new int[m_nAllNum];
memset(m_npValue,0,m_nAllNum);
for(int i=0; i<m_nAllNum; i++)
{
m_npValue[i] = i;
}
}
}
void CAnswer1Dlg::OperShuffle(int &nCount)
{
int* n_pA = new int [m_nAllNum/2];
memset(n_pA,0,m_nAllNum/2);
int* n_pB = new int [m_nAllNum-m_nAllNum/2];
memset(n_pB,0,m_nAllNum-m_nAllNum/2);
int* n_pNew = new int [m_nAllNum];
memset(n_pNew,0,m_nAllNum);

for(int i=0; i<m_nAllNum; i++)
{
if(i < m_nAllNum/2)
n_pA[i] = m_npValue[i];
else
n_pB[i-m_nAllNum/2] = m_npValue[i];
}
while(TRUE)
{
int i = 0; int n = 0;
for(;;) // 洗牌
{
n_pNew[n] = n_pA[i];
n_pNew[++n] = n_pB[i];
n++;
i++;
if(n>=m_nAllNum)
break;
}
OperMakeLog(n_pNew,m_nAllNum);
nCount++; // 洗牌次数++
if(OperCheck(n_pNew)) // 校验
{
break;
}
for(int k=0; k<m_nAllNum; k++)
{
if(k < m_nAllNum/2)
n_pA[k] = n_pNew[k];
else
n_pB[k-m_nAllNum/2] = n_pNew[k];
}
OperMakeLog(n_pA,m_nAllNum/2);
OperMakeLog(n_pB,m_nAllNum-m_nAllNum/2);
Sleep(10);
}
}


BOOL CAnswer1Dlg::OperCheck(int* pNew) // 检验顺序是否已经完美
{
for(int i=0; i<m_nAllNum; i++)
{
if(pNew[i] != i)
return FALSE;
}
return TRUE;
}
void CAnswer1Dlg::OperMakeLog(int* pTemp,int nNum) //记录日志
{
FILE * fp = NULL;
if(fp = fopen("a.txt","a"))
{
fprintf(fp,"\r\n this:");
for(int i=0;i<nNum;i++)
{
fprintf(fp,"%d",pTemp[i]);
}
fclose(fp);
}
}


当输入牌数为52时,的确是8次就完美了!!
但是这里得注意左右手,我刚开始这里:

n_pNew[n]   = n_pA[i];
n_pNew[++n] =   n_pB[i];
n_pNew[++n] =   n_pB[i];

写成:

n_pNew[n]   = n_pB[i];
n_pNew[++n] =   n_pA[i];
n_pNew[++n] =   n_pA[i];

就不是8次,所以这根左右手的先后顺序还是有关系的!!!



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值