C語言 洗牌
假設我們有 2n 張牌,它們以 1, 2, ..., n, n+1, ..., 2n 編號並在開始時保持著這種順序。一次洗牌就是將牌原來的次序變為 n+1, 1, n+2, 2, ..., 2n, n,也就是將原來的前 n 張牌放到位置 2, 4, ..., 2n,並且將余下的 n 張牌按照他們原來的次序放到奇數位置 1, 3, ..., 2n-1。已經證明對於任何一個自然數 n,這 2n 張牌經過一定次數的洗牌就回到原來的次序。但我們不知道對於一個特定的 n,需要幾次洗牌才能將牌洗回原來的次序。
輸入:
牌張數的一半n,即初始情況下一共有2n張牌
輸出:
將牌洗回原來的次序所需要的洗牌次數
如輸入10
輸出6
這個算法怎麼設計...誰能提供點思路啊,謝謝了。
最佳回答:
下面是正確的代碼,沒有用鏈表,通過4個數組來做的,必要的注釋我都加了。不理解可以問我。
cout相當於printf,cin相當於scanf。
#include "iostream"
using namespace std;
int main()
{
int num;
cout << "請輸入特定數n:";
cin >> num;
int *arry = new int[2*num];
int *temp = new int[2*num];
int *t1 = new int[num];
int *t2 = new int[num];
//初始化數組
for(int j=0;j<2*num;j++)
{
arry[j] = temp[j] = j;
}
//以下是循環部分
bool gogo = true;
int count = 0;
while(gogo)
{
//更新奇、偶數組
for(int i=0; i<2*num; i++)
{
if(i<num)
t1[i] = temp[i];
else
t2[(i-num)] = temp[i];
}
//重組temp數組
for(i=0; i<2*num; i++)
{
if(i%2==0)
temp[i] = t2[i/2] ;
else
temp[i] = t1[(i-1)/2];
}
//判斷重組後的數組temp是否和原來的數組一樣
for(i=0; i<2*num; i++)
{
if(arry[i] != temp[i])
{
break;
}
}
//如果完全相同,則此時 i==2n;
if(i==2*num)
gogo = false;
count++;
}
cout << count << "次後數組恢復到原來的次序。";
return 0;
}