题目:
洗之前不是乱牌,而是已经按顺序排好的(一般新牌打开就是这样)
完美洗牌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次,所以这根左右手的先后顺序还是有关系的!!!